Kiedy należy wykonywać obliczenia w interfejsie?

21

Mój zespół pracuje nad aplikacją finansową opartą na WEBie, a kolega z koleżanki spierał się, gdzie przechowywać obliczenia - tylko w back-endie, czy też w front-endie?

Krótkie wyjaśnienie: Używamy Java (ZK, Spring) dla frontonu i Progress 4gl dla back-endu. Obliczenia, które obejmują niektóre trudne obliczenia matematyczne i dane z bazy danych, są przechowywane w zapleczu, więc nie mówię o nich. Mówię o sytuacji, w której użytkownik wprowadza wartość X, a następnie dodaje się ją do wartości Y (pokazanej na ekranie), a wynik jest wyświetlany w polu Z. Czyste i proste operacje jQuery, to znaczy.

Więc jaka byłaby najlepsza praktyka tutaj:

1) Dodać wartości za pomocą JavaScript, które oszczędzają przechodzenie do zaplecza i wstecz, a następnie zweryfikować je na zapleczu „przy zapisywaniu”?

2) Zachowaj całą logikę biznesową w tym samym miejscu - dlatego przenieś wartości do zaplecza i wykonaj tam obliczenia?

3) Wykonaj obliczenia w interfejsie; następnie wyślij dane do zaplecza, zweryfikuj je tam, wykonaj obliczenia ponownie i tylko jeśli wyniki są prawidłowe i równe, wyświetl je użytkownikowi?

4) Coś jeszcze?

Uwaga: Przeprowadzamy podstawowe sprawdzanie poprawności w Javie, ale większość z nich wciąż znajduje się w zapleczu, podobnie jak cała logika biznesowa.

Zwiększenie ilości danych, które zostałyby wysłane przez ponowne obliczenie wszystkiego w zapleczu, nie stanowiłoby problemu (mały rozmiar XML; serwery i przepustowość wytrzymałyby zwiększoną liczbę operacji wykonywanych przez użytkowników).

IgnasK
źródło
1
Ogólna zasada: kiedy używa silnie napisanego języka.
Den
1
Zautomatyzowane testowanie jednostek będzie łatwiejsze, jeśli cała logika znajduje się w zapleczu. Jeśli 90% ma być zapleczem, a 10% może być w zapleczu, to postawiłbym 100% na zapleczu.
Ian
3
@Ian: możesz również przeprowadzać automatyczne testy jednostkowe kodów frontend, jeśli dobrze ustrukturyzujesz swój kod.
Lie Ryan,
1
Ogólna zasada: ilekroć możesz tego uniknąć.
goldilocks
3
Ogólna zasada: załóż, że użytkownik włamuje się do JavaScript i wykonuje własne obliczenia. Z punktu widzenia bezpieczeństwa obliczenia należy wykonać na zapleczu. Możesz także zrobić jedno i drugie: JS może zapewnić szybszą informację zwrotną, ale obliczenia, które faktycznie się liczą, są wykonywane na serwerze.

Odpowiedzi:

36

Jak zawsze, takie decyzje wiążą się z kompromisem między różnymi celami, z których niektóre są ze sobą sprzeczne.

  • Wydajność sugeruje wykonanie obliczeń w interfejsie - zarówno dlatego, że komputer użytkownika zużywa więcej energii, a serwer zużywa mniej, a także dlatego, że użytkownik widzi szybsze informacje zwrotne, co poprawia komfort użytkowania.

  • Bezpieczeństwo wymaga, aby wszelkie operacje zmieniające stan nie mogły polegać na sprawdzaniu lub obliczaniu danych na komputerze klienckim, ponieważ komputer kliencki może być pod kontrolą złośliwego atakującego. Dlatego musisz sprawdzić wszystko, co pochodzi z niezaufanych źródeł po stronie serwera.

  • Wydajność i łatwość programowania sugerują, że nie powinieneś wykonywać tego samego obliczenia dwa razy z powodu zmarnowanego wysiłku.

Na pozór brzmi to tak, jakby wszystko trzeba było zrobić po stronie serwera, ale nie zawsze tak jest. Jeśli możesz łatwo utrzymać zduplikowany kod (np. Automatycznie generując sprawdzanie javascript z walidatora Java po stronie serwera), powtórzenie obliczeń może być dobrym rozwiązaniem. Jeśli wszystkie dane są nieistotne, np. Jeśli użytkownik może oszukiwać tylko siebie, a nie ciebie, jeśli manipuluje wartościami, weryfikacja po stronie serwera nie jest konieczna. Jeśli twój czas reakcji jest zdominowany przez zupełnie inne wąskie gardła, tak że opóźnienie w obie strony nie jest odczuwalne, to względy UX nie są decydujące itp. Dlatego musisz rozważyć, jak silne jest każde z tych nacisków w twojej sytuacji i odpowiednio zdecydować .

Kilian Foth
źródło
4
Chciałbym dodać, że Programming efficiency and maintainability suggests that you shouldn't do the same computation twice because of the wasted effort.to nie jest poprawne, ponieważ [1] Walidacja w interfejsie może dostarczyć użytkownikowi szybkiej informacji zwrotnej, aby w razie potrzeby wprowadzić poprawki. [2] Walidacja w back-endie nie jest tak responsywna, a zatem nie zapewnia użytkownikowi najlepszej okazji do wprowadzenia poprawek. Użytkownik musiałby poczekać i powtórzyć więcej pracy. Myślę więc, że te dwie walidacje nie są dokładnie takie same.
Poinformowano
9
To nie jest to, co chciałem, aby przedostać się na drugą - konserwacji ma oznaczać „nie powtarzać sobie”, i zgodnie z tą zasadą powtarzanie jest na pewno źle. Jeśli nie było innych okoliczności, nie powinieneś tego robić. Fakt, że jest to mimo wszystko często jest dobrym pomysłem, ponieważ tam inne względy, które są sprzeczne z tą zasadą, czyli lepiej użyteczność dzięki szybkiej realizacji.
Kilian Foth,
@randomA Błędnie stosujesz tę zasadę, jeśli masz na myśli, że coś, co musi zostać zweryfikowane na serwerze, powinno być obliczone tylko na serwerze, ponieważ jeśli „wartość zweryfikowana przez serwer” (lub cokolwiek od niej zależnego) jest zwracana do klienta w pewnym momencie odesłanym z powrotem na serwer, i tak musisz to zweryfikować - bezużyteczne. Albo potrzebujesz systemu bezpiecznych referencji, który może być jeszcze bardziej nieefektywny. Powiedziałbym, że jeśli możesz wykonać obliczenia na kliencie, zrób to na kliencie , ale także nigdy nie ufaj temu, co mówi ci klient .
goldilocks
@goldilocks To, co powiedziałeś pogrubioną czcionką, jest również tym, co zgadzam się, musisz zweryfikować wszystko na zapleczu. Chodziło mi o to, że: sprawdzanie poprawności w interfejsie jest bardziej responsywne, więc nie do końca takie samo jak sprawdzanie poprawności w zapleczu.
InformedA
13

Istnieją silne powody, aby wykonywać obliczenia w backend

  • Logika biznesowa nie należy do warstwy prezentacji
  • Logika biznesowa w JavaScript stanowi zagrożenie
  • Zakładasz, że istnieje relacja jeden-front-end -> jeden-back-end, co nie zawsze jest prawdą , back-endy powinny być uważane za zdolne lub obsługujące więcej niż jedną aplikację front-end, więc nie możesz niczego założyć.
  • Jeśli obliczenia wykorzystują dużą ilość danych, trzymanie ich w interfejsie nie byłoby efektywne
  • Jeśli obliczenia wykorzystują bazę danych, nie będzie można jej replikować w interfejsie

Moja rekomendacja

  • Niech baza danych wymusi jak najwięcej reguł biznesowych w modelu, w tym klucze obce, klucze podstawowe, ograniczenia sprawdzania i wyzwalacze
  • Niech warstwa biznesowa zgłasza wyjątki, gdy reguły biznesowe nie są spełnione (albo dlatego, że baza danych zwróciła błąd, albo dlatego, że sama warstwa biznesowa zweryfikowała dane)
  • Jeśli i tylko wtedy, gdy czas odpowiedzi jest niedopuszczalny, wykonaj walidacje lub przetwarzanie wstępne za pomocą Ajax (praca nie będzie tak naprawdę wykonana w JavaScript, będzie to zrobione w backendie bez konieczności ponownego ładowania strony)
  • Możesz dokonać prostej weryfikacji w JavaScript, np. Nie zezwalając na pustą wartość, wartości, które są zbyt długie lub poza zakresem (w tym drugim przypadku możesz chcieć wygenerować zakresy w zapleczu)
Tulains Córdova
źródło
2
Problem z egzekwowaniem reguł biznesowych w bazie danych polega na zgłaszaniu naruszeń do interfejsu! Jeśli interfejs wymusza reguły biznesowe, może szybko przekazać użytkownikowi znaczące komunikaty o błędach. Jeśli back-end to robi, jest dużo niezgrabnego dwukierunkowego ruchu między przednimi i tylnymi końcami, ponieważ błędy są zgłaszane pojedynczo.
James Anderson
@JamesAnderson Nie ma już „interfejsu”. Może istnieć kilka interfejsów do tej samej bazy danych lub kilka baz danych do kilku interfejsów. Ponadto egzekwowanie reguł biznesowych przez zaplecze nie oznacza, że ​​front-end nie może tego robić. Podkreśliłem to w drugim punkcie.
Tulains Córdova