Когда уместно делать вычисления в front-end?

21

Моя команда разрабатывает финансовое приложение на основе WEB, и с коллегой возник спор о том, как сохранить расчеты - чисто бэкэнд или некоторые из них тоже?

Краткое объяснение: Мы используем Java (ZK, Spring) для front-end и Progress 4gl для back-end. Расчеты, которые включают в себя некоторую хардкорную математику и данные из базы данных, хранятся в бэк-энде, поэтому я не говорю о них. Я говорю о ситуации, когда пользователь вводит значение X, затем оно добавляется к значению Y (показано на экране), и результат отображается в поле Z. Я имею в виду чистые и простые операции jQuery-ish.

Итак, что было бы лучшей практикой здесь:

1) Добавить значения с помощью JavaScript, который избавляет от перехода в бэкэнд и обратно, а затем проверять их в бэкэнде «при сохранении»?

2) Храните всю бизнес-логику в одном месте - поэтому перенесите значения в бэкэнд и сделайте там расчеты?

3) Делать расчеты во внешнем интерфейсе; затем отправить данные в бэкэнд, проверить их там, выполнить вычисления снова и только, если результаты верны и равны, отобразить их пользователю?

4) Что-то еще?

Примечание. Мы выполняем некоторую базовую проверку в Java, но большая ее часть все еще находится в бэк-энде, как и вся остальная бизнес-логика.

Увеличение объема данных, которые будут отправлены путем пересчета всего в бэкэнде, не будет проблемой (небольшой размер XML; серверы и пропускная способность будут выдерживать увеличение количества операций, выполняемых пользователями).

IgnasK
источник
1
Основное правило: когда он использует строго типизированный язык.
День
1
Автоматическое модульное тестирование будет проще, если вся логика находится на заднем плане. Если 90% должно быть задним числом, а 10% может быть задним числом, то я бы положил 100% на заднем конце.
Ян
3
@Ian: вы можете выполнять автоматическое модульное тестирование для кодов переднего плана, если вы хорошо структурируете свой код.
Ли Райан
1
Правило большого пальца: всякий раз, когда вы можете сойти с рук.
Златовласка
3
Основное правило: предположите, что пользователь взламывает ваш JavaScript и выполняет свои собственные вычисления. С точки зрения безопасности, вычисления должны быть сделаны на серверной части. Вы можете сделать и то и другое: JS может обеспечить более быструю обратную связь, но вычисления, которые фактически учитываются, выполняются на сервере.

Ответы:

36

Как всегда, такие решения предполагают компромисс между различными целями, некоторые из которых противоречат друг другу.

  • Эффективность предполагает, что вы выполняете вычисления во внешнем интерфейсе - и потому, что таким образом компьютер пользователя потребляет больше энергии, а ваш сервер потребляет меньше, а также потому, что пользователь видит более быструю обратную связь, что улучшает взаимодействие с пользователем.

  • Безопасность требует, чтобы любые операции с изменением состояния не могли полагаться на данные, проверяемые или вычисляемые на клиентском компьютере, поскольку клиентский компьютер может находиться под контролем злоумышленника. Следовательно, вы должны проверять все, что поступает из ненадежных источников на стороне сервера.

  • Эффективность программирования и ремонтопригодность предполагают, что вы не должны делать одни и те же вычисления дважды из-за потраченных усилий.

Внешне это звучит так, как будто все должно быть сделано на стороне сервера, но это не всегда так. Если вы можете легко поддерживать дублированный код (например, автоматически генерируя валидатор javascript из вашего валидатора Java на стороне сервера), то повторение вычислений может быть хорошим решением. Если все эти данные не важны, например, если пользователь может обманывать только себя, а не вас, если они манипулируют значениями, то проверка на стороне сервера не требуется. Если в вашем времени отклика преобладают совершенно разные узкие места, так что задержка прохождения сигнала туда и обратно не ощутима, то соображения UX не являются решающими и т. Д. Поэтому вы должны учитывать, насколько сильным является каждое из этих давлений в вашей ситуации, и принимать соответствующие решения. ,

Килиан Фот
источник
4
Я хотел бы добавить, что Programming efficiency and maintainability suggests that you shouldn't do the same computation twice because of the wasted effort.это не правильно, потому что [1] Проверка во внешнем интерфейсе может обеспечить быструю обратную связь с пользователем для внесения исправлений, если это необходимо. [2] Валидация в бэк-энде не так отзывчива и, следовательно, не дает пользователю лучшей возможности внести исправления. Пользователь должен будет подождать и повторить больше работы. Поэтому я думаю, что две проверки не совсем одинаковы.
InformedA
9
Это не то , что я хотел бы получить по - ремонтопригодность делает подразумевает «не повторяться», и в соответствии с этим принципом повторение, конечно , плохо. Если не было других соображений, вы не должны этого делать. Тот факт , что это все - таки часто хорошая идея заключается в том, потому что есть другие соображения , которые противоречат этому принципу, то есть лучше практичности через быстрый поворот.
Килиан Фот
@randomA Вы неправильно применяете этот принцип, если имеете в виду, что что-то, что должно быть проверено на сервере, должно рассчитываться только на сервере, потому что если «проверенное сервером значение» (или что-то зависящее от него) возвращается клиенту, то в какой-то момент, отправленный обратно на сервер, вы все равно должны проверить его - бесполезно. Или же вам нужна система безопасных ссылок, которая может быть еще более неэффективной. Я бы сказал, если вы можете сделать расчет на клиенте, сделать это на клиенте , но также никогда не доверяйте тому, что клиент говорит вам .
Златовласка
@goldilocks То, что вы сказали жирным шрифтом, также является тем, с чем я согласен, вы должны проверить все на сервере. Моя точка зрения заключалась в том, что проверка на внешнем интерфейсе более отзывчива, поэтому не полностью совпадает с проверкой на внутреннем.
InformedA
13

Существуют веские причины для выполнения расчетов в бэкэнде

  • Бизнес-логика не относится к уровню представления
  • Бизнес-логика в JavaScript представляет угрозу
  • Вы предполагаете, что есть отношение «один фронт-энд -> один-конец», которое не всегда верно , о бэкэндах следует думать как о способных или обслуживающих более чем одно интерфейсное приложение, таким образом, вы не можете ничего предположить.
  • Если в вычислениях используется большое количество данных, было бы неэффективно хранить их во внешнем интерфейсе.
  • Если в расчетах используется база данных, вы не сможете скопировать ее в интерфейс

Моя рекомендация

  • Сделайте так, чтобы база данных применяла столько бизнес-правил, сколько возможно в модели, включая внешние ключи, первичные ключи, проверочные ограничения и триггеры.
  • Пусть бизнес-уровень генерирует исключения, когда бизнес-правила не соблюдаются (либо потому, что база данных возвратила ошибку, либо потому, что бизнес-уровень сам проверил данные)
  • Если и только если время отклика неприемлемо, выполните валидацию или предварительную обработку с использованием Ajax (работа не будет действительно выполнена в JavaScript, она будет выполнена в бэкэнде без перезагрузки страницы)
  • Вы можете выполнить простую проверку в JavaScript, например, не допуская пустого значения или значений, которые слишком длинные или выходят за пределы диапазона (для последнего может потребоваться сгенерировать диапазоны в бэкэнде)
Тулаинс Кордова
источник
2
Проблема с тем, что база данных обеспечивает соблюдение бизнес-правил, заключается в том, что она сообщает о нарушениях во внешний интерфейс! Если пользовательский интерфейс применяет бизнес-правила, он может быстро отправить пользователю значимые сообщения об ошибках. Если серверная часть делает это, существует много неуклюжего двустороннего трафика между интерфейсом и серверной частью, поскольку ошибки сообщаются по одной за раз.
Джеймс Андерсон
@JamesAnderson Больше нет «внешнего интерфейса». В одной базе данных может быть несколько интерфейсов или несколько баз данных для нескольких интерфейсов. Кроме того, наличие бэк-энда для обеспечения соблюдения бизнес-правил не означает, что клиентскому интерфейсу это запрещено. Я подчеркнул это во втором пункте.
Тулаинс Кордова