Zarządzanie weryfikacjami po stronie klienta i serwera w jednym miejscu

17

Jestem w 100% zaangażowany w sprawę, że zdecydowanie należy używać zarówno weryfikacji danych po stronie klienta, jak i serwera.

Jednak w ramach i środowiskach, w których pracowałem, podejścia, które widziałem, nigdy nie były SUCHE. Przez większość czasu nie ma planu ani wzorca - weryfikacje są zapisywane w specyfikacji modelu, a weryfikacje są zapisywane w formularzu w widoku. (Uwaga: większość moich doświadczeń z pierwszej ręki dotyczy Railsów, Sinatry i PHP w / jQuery)

Zastanawiając się nad tym, wydaje się, że nie byłoby trudno stworzyć generator, który, biorąc pod uwagę zestaw walidacji (np. Nazwa modelu, pole (pola), warunek), mógłby wytworzyć zarówno niezbędny materiał po stronie klienta, jak i po stronie serwera. Alternatywnie, takie narzędzie może pobierać weryfikacje po stronie serwera (takie jak validateskod w modelu ActiveRecord) i generować weryfikacje po stronie klienta (takie jak wtyczki jQuery, które następnie byłyby stosowane do formularza.

Oczywiście powyższe jest po prostu zadumaniem „hej, miałem ten pomysł”, a nie formalną propozycją. Tego rodzaju rzeczy są z pewnością trudniejsze niż się wydawało, kiedy pomysł mnie uderzył.

To prowadzi mnie do pytania: jak podchodziłbyś do zaprojektowania techniki „napisz raz, uruchom na serwerze i kliencie” do sprawdzania poprawności danych?

Powiązane tematy: Czy istnieją takie narzędzia dla konkretnych platform lub technologii klient-serwer? Jakie są główne przeszkody lub wyzwania związane z próbą utrzymania tylko jednego zestawu walidacji?

przedpola
źródło

Odpowiedzi:

6

Z mojego ograniczonego doświadczenia wynika, że ​​wymagane są walidacje

  1. Poziom prezentacji przy użyciu HTML,
  2. na poziomie po prezentacji (tj. walidacja Javascript),
  3. na poziomie kombinacji, gdzie interakcje między wieloma polami muszą być wspólnie zatwierdzane,
  4. na poziomie logiki biznesowej i
  5. na poziomie bazy danych.

Każdy z nich ma inny język, czas i wyzwalacze. Na przykład sprawdzanie poprawności pola, zanim cały rekord nie będzie spójny, nie ma sensu, chyba że chcesz zweryfikować tylko jeden element. Ograniczenia na poziomie bazy danych muszą mieć zastosowanie tylko na końcu przed zatwierdzeniem i nie mogą być łatwo wykonane pojedynczo.

Pokrewna koncepcja polega na tym, że reprezentowanie danych różni się między poszczególnymi poziomami. Prostym przykładem jest przeglądarka internetowa reprezentująca fragment tekstu, być może CP1290, podczas gdy baza danych reprezentuje go w UTF-8; długości dwóch łańcuchów różnią się, więc egzekwowanie ograniczeń długości staje się niewygodne.

BobDalgleish
źródło
tak, różne języki i ramy sprawiają, że jest to niepraktyczne. Nie „nieodwracalne”, ponieważ przy wystarczających zasobach można to zrobić, ale pisanie automatycznych konwerterów na języki i między nimi jest OGROMNYM zadaniem. Wykonanie tego w rozsądnym terminie, a następnie utrzymanie go w związku ze zmianą odpowiednich technologii byłoby dużym nakładem pracy.
Michael Durrant,
Zdecydowanie jest prawdą, że wielu weryfikacji po stronie serwera (np. Unikatowość pola) nie można wykonać w przeglądarce. Jednak prawdą jest również to, że wszelkie weryfikacje po stronie klienta muszą być powtarzane na serwerze, ponieważ nie można ufać klientowi. Właśnie w tym miejscu widzę, że SUSZENIE jest szczególnie przydatne. Na przykład widziałem klejnot, który rozszerza Railsy, form_foraby automatycznie zapewniał kod sprawdzający po stronie klienta, który jest bardzo przydatny.
Dan
5

Jednym z czynników, który często ogranicza rozwiązania, jest obieg sieci. Klient powinien zweryfikować dane użytkownika bez wysyłania wiadomości przez sieć. Innymi słowy, gdy użytkownik naciśnie przycisk przesyłania, klient powinien zweryfikować dane lokalnie.

Po pierwsze, załóżmy, że nie mamy tego ograniczenia. Możemy komunikować się z punktem końcowym sieci, który jest dobry w artykułowaniu problemów związanych z weryfikacją. Na przykład, jeśli prześlesz do niego nowy rekord użytkownika, zamiast odpowiadać waniliowym kodem błędu HTTP, może zwrócić szczegółową odpowiedź JSON wyszczególniającą problemy, a klient inteligentnie zaktualizuje wyświetlacz, aby odzwierciedlić napotkane problemy. Punkt końcowy pełni rolę bramy sprawdzania poprawności.

Jest SUCHY, ale nie bez wad. Po pierwsze, zależy to od obłożenia sieci obciążającego nasz serwer walidacjami, które mogły być obsługiwane po stronie klienta. Po drugie, projekt przewiduje, że wszystkie operacje CRUD będą odbywać się za pośrednictwem naszych punktów końcowych, ale co z tym, kiedy programiści i procesy omijają naszą warstwę dostępu do danych, idąc bezpośrednio do bazy danych ?

Przyjrzyjmy się ponownie naszemu rozwiązaniu, aby przezwyciężyć te wady. Zamiast tego przechowujmy i przekażmy nasze walidacje jako metadane:

{field: 'username', type: 'required'}
{field: 'username', type: 'unique'} //requires a network roundtrip
{field: 'password', type: 'length', min: 10, max: 50}
{field: 'password', type: 'contains', characters: ['upper', 'special', 'letter', 'number']}

Zarówno klient, jak i serwer miałyby pewien mechanizm (np. Silnik) do interpretowania i stosowania tych danych. (Niektórzy nazywają to wolną monadą, ponieważ oddziela deklaratywną część od swojego interpretera). W JavaScript możemy mapować każdą informację na działające funkcje. Aby uruchomić, możemy nauczyć każdą warstwę naszej architektury, w tym naszą bazę danych, aby konsekwentnie wymuszać sprawdzanie poprawności.

Mario T. Lanza
źródło
Jak opisujesz pole, gdy pole jest inaczej reprezentowane w przeglądarce internetowej, transporcie, języku implementacji i bazie danych? Na przykład liczba bajtów wymaganych do przedstawienia pola ciągu różni się, gdy używany jest CP1290 (IE), UTF-8 (JSON), UTF-8 (C #) lub UCS-16 (Oracle). Co oznacza ograniczenie długości? Co ważniejsze dla przeglądarki, kiedy reprezentacja znaków zależy od przeglądarki i systemu operacyjnego?
BobDalgleish
Ograniczenia te są wymyślone jako model mentalny dla ludzi. Twoim zadaniem jako programisty jest wyodrębnienie różnic w maszynie, aby osoba nie musiała przejmować się różnicami technicznymi.
Mario T. Lanza,
Całkowicie przegapiłeś punkt. Jak dotąd nikt nie przedstawił abstrakcji, która pozwala na weryfikację od końca do końca, z jedną specyfikacją. Z PO „pisz raz” oznacza, że ​​posiadanie różnych klauzul dotyczących różnych etapów nie kwalifikuje się. Podobnie, nie widzę nic w proponowanej walidacji, która dotyczyłaby walidacji między polami lub między obiektami.
BobDalgleish,
Walidacje między polami / obiektami nie są zbyt rozciągliwe. Metadane reprezentują tylko związek. Pisz raz oznacza, że ​​piszę raz jedną weryfikację i mam ją egzekwować w wielu witrynach, co się dzieje. Dodajesz metadane do tabeli. Te metadane są odbierane przez dowolną witrynę, a prosta klasa / narzędzie / silnik wymusza ograniczenie.
Mario T. Lanza
1
Taki język walidacji byłby niezwykle przydatny. Może zastąpić może jedną trzecią kodu związanego z aplikacjami internetowymi intensywnie korzystającymi z interfejsu użytkownika.
BobDalgleish,
2

Jednym ze sposobów byłoby użycie tego samego języka / frameworku zarówno po stronie serwera, jak i klienta.

Na przykład

Node.js :: Klient / Serwer w JavaScript GET :: Klient / Serwer w Javie

W takim przypadku większość kodu „Domain Object” byłaby wspólna, co obejmowałoby sprawdzanie poprawności. Framework wywoła kod zgodnie z wymaganiami. Np. Ten sam kod byłby wywoływany w przeglądarce przed „przesłaniem” i w serwisie WWW po stronie serwera.

EDYCJA (czerwiec / 2014): Z Javą 8 można teraz również łatwo zintegrować kod sprawdzający JS z aplikacjami Java. Java 8 ma nowy silnik wykonawczy JS, który jest bardziej trwały (np. Korzysta z invokeDynamic).

Shamit Verma
źródło
Jeśli chodzi o bazę danych SQL, nie wiem, jak to będzie działać.
Michael Durrant,
Nie rozwiązuje również problemu, że przeglądarka i system operacyjny wpływają na domenę wejściową.
BobDalgleish,
@Micheal Durrant, do sprawdzania poprawności bazy danych są implementowane jako ograniczenia DB (takie jak klucz obcy, unikalny itp.). BobDalgleish, 1. Problem kompatybilności przeglądarki / systemu operacyjnego można złagodzić za pomocą biblioteki, która dostosowuje środowisko uruchomieniowe zgodnie z przeglądarką (np. Sencha) 2. Zgodność przeglądarki nie ma wpływu na „logiczne” części kodu, takie jak sprawdzanie poprawności, problemy ze zgodnością są zwykle wokół renderowania DOM / UI.
Shamit Verma
0

Właśnie myślałem o tym samym problemie. Myślałem o użyciu ANTLR, aby uzyskać abstrakcyjne drzewo składniowe zarówno w języku C #, jak i javascript. Stamtąd używasz programów do wklejania drzew, aby zastosować działania określone w języku do obiektów, które mają zostać sprawdzone.

Zatem możesz przechowywać opis wymaganej walidacji w dowolnym miejscu - ewentualnie w bazie danych.

Tak podchodziłbym do problemu.

Marcus
źródło