Как избежать повторения бизнес-логики между клиентом и сервером?

по мере роста потребностей веб-приложений я обнаружил, что пишу все больше и больше веб-приложений, управляемых API. Я использую фреймворки, такие как AngularJS, для создания богатых веб-клиентов, которые взаимодействуют с этими API. В настоящее время я использую PHP (Lumen или Laravel) для серверной стороны / API.

проблема в том, что я часто повторяю бизнес-логику между клиентом и сервером.

когда я говорю бизнес-логику, я имею в виду такие правила, как следующие Для формы заказа:

  • вы можете купить X, если вы покупаете Y.
  • вы не можете купить Y, если у вас есть Z.
  • если вы покупаете 10 из них, вы получаете скидку 10%.
  • Высота x Ширина x глубина x стоимость = конечная стоимость.
  • высота должна быть между 10 и 20 если ширина больше 5.
  • и т. д. и т. п.

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

Я имею в виду три решения:

  1. сделайте все, что требует бизнес-логики, вызов ajax в API. Вся бизнес-логика будет жить в одном месте и может быть протестирован. Это может быть медленным, так как клиенту придется ждать каждого они делают в форме заказа, чтобы получить обновленные значения и результаты. Наличие очень быстрого API поможет в этом. Основным недостатком является то, что это может не работать хорошо, когда пользователи находятся на плохих соединениях (мобильных устройствах).

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

  3. доверие клиента!?! Написать всю бизнес-логику на стороне клиента и предположить, что они не вмешивались в данные. В моем текущем сценарии я работаю над построителем цитат, который всегда будет пересматриваться человеком, поэтому, возможно, это действительно нормально.

честно говоря, я не доволен ни одним из решений, поэтому я обращаюсь к сообщество за советом. Я хотел бы услышать Ваше мнение или подходы к этой проблеме!

8 ответов


вы можете сделать еще одну вещь.

создайте код проверки и бизнес-логики только с помощью JavaScript. Но сделайте его как можно более свободно связанным. Если возможно, возьмите JSON как вход и JSON как выход.

затем настройте сервер nodejs рядом с сервером PHP, чтобы обслуживать эту логику на стороне клиента. Так что на стороне клиента его можно использовать без вызова AJAX.

затем со стороны сервера (PHP), когда вам нужно проверить и запустить все эти бизнес-логические вызовы cURL в nodejs для проверки этих данных. Это означает, что это http-вызов с сервера PHP на сервер nodejs. Сервер Nodejs будет иметь другой код, который будет принимать эти данные и проверять с тем же кодом и возвращать результат.

таким образом, вы можете сделать

  1. более быстрое развитие (одно место, чтобы проверить вашу логику)
  2. более быстрое выполнение клиентского кода (нет необходимости ajax, так как те же файлы javascript проверки обслуживаются nodejs к вашей стороне клиента)
  3. вся бизнес-логика перейдет на сервер nodejs. (При изменении бизнес-логики вам нужно коснуться только этой части, так что в ближайшем будущем, если вам нужно создать некоторые другие интерфейсы, вы можете использовать этот сервер для проверки ваших данных. Он будет работать так же, как ваш сервер бизнес-правил)

только то, что вам нужно сделать, это настройка nodejs рядом с сервером PHP. Но вам не нужно изменять все ваши код на nodejs сервер.


У меня была такая же проблема, когда я решил создать приложение с использованием Laravel для заднего конца и Angular 2 для переднего конца. И мне кажется, что пока нет решения, чтобы избежать дублирования бизнес-логики, потому что:

на данный момент PHP и JavaScript не могут быть преобразованы друг в друга. Было бы неплохо, если бы мы могли использовать один и тот же язык для написания бизнес-логики, а затем встроить их как в back-end, так и в front-end. С этого момента она ведет меня к другому. точка:

чтобы достичь цели, мы должны написать бизнес-логику только на одном языке, и до сих пор JavaScript является лучшим решением. Как вы знаете, скрипт TypeScript/EMCA поможет нам написать код способом ООП. Метеор инфраструктура framework NodeJS помогает нам писать код на JavaScript для работы в обеих сторонах Back-end и front-end.

поэтому, с моей точки зрения, мы можем использовать TypeScript/EMCA для написания пакетов для бизнес-логики, например класса для проверка, написанная на JavaScript, может быть реализована с обеих сторон, поэтому вы просто пишете только один раз, но она также будет вызываться дважды из front-end и back-end.

Это моя точка зрения. Надеюсь увидеть некоторые другие решения для этой очень интересной темы.


одним из возможных решений является объявление правил проверки на декларативном абстрактном языке, таком как XML или схема JSON.

затем на стороне клиента, скажем AngularJS -- вы можете преобразовать эти правила в готовую форму визуализации. Итак, теперь на стороне клиента вы получаете формы, которые проверяют объявленные правила.

затем на вашем сервере API вам нужно создать многоразовый механизм проверки, который будет проверять на основе определенного правила.

то, что вы получаете, - это одно место, ваша схема JSON или где вы декларативно определяете свои правила, что ваши правила формы и проверки определены.


Я также был в этом положении, когда работал над некоторыми из моих собственных проектов. Всегда заманчиво использовать мощность устройства клиента для выполнения тяжелой работы, а затем просто проверить результаты на стороне сервера. Что приведет к появлению бизнес-логики дважды, как переднего, так и заднего.

Я думаю, что Вариант 1-лучший вариант, он имеет наибольший смысл и кажется наиболее логичным. Если вы хотите расширить свое веб-приложение до собственных мобильных приложений в будущем вы сможете повторно использовать всю бизнес-логику, вызвав эти API. Для меня это огромная победа.

Если беспокойство, если делает слишком много запросов API, и это может повлиять на мобильную производительность, то, возможно, попытаться объединить некоторые из запросов и выполнить одну проверку в конце? Поэтому вместо проверки каждого поля в форме выполните проверку, когда пользователь отправит всю форму. Также большинство интернет-соединения будет достаточно, если вы держите запрос и ответ данные сведены к минимуму, так что я не буду беспокоиться об этом.

большая проблема, с которой я обычно сталкиваюсь, заключается в том, что, поскольку ваше веб-приложение будет разбито на разделы, каждый раздел вызывает соответствующие API. Состояние приложения гораздо сложнее понять, так как пользователь может прыгать между этими состояниями. Вам нужно будет очень тщательно подумать о путешествии пользователя и убедиться, что процесс не глючит.

вот некоторые из общих проблем, с которыми мне пришлось иметь дело с:

  • отображает ли интерфейсная ошибка, если API возвращает ее?
  • если пользователь допустил ошибку и отправил форму, он должен увидеть ошибку. Но как только пользователь исправил ошибку и отправляет снова, ошибка должна скрываться, и сообщение об успехе теперь должно отображаться.
  • что делать, если API глючит или подключение к интернету неустойчиво, поэтому ничего не возвращается. Будет ли передний конец висеть?
  • что при наличии нескольких ошибок сообщения, может / делает front-end отображать их все?

Я бы рекомендовал иметь много модульных тестов на переднем конце, чтобы убедиться, что он стабилен, даже если бизнес-логика находится только на заднем конце.


Я считаю, что Вариант 1-лучший в будущем. API first development позволяет тестировать и корректно работать всю бизнес-логику и предоставлять интерфейсам доступ. Вы никогда не должны доверять пользователю!

первая разработка power API неограничена по сравнению с кодированием одной и той же логики снова и снова для каждого необходимого интерфейса.


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

на стороне клиента и на стороне сервера


прежде всего: никогда не доверяй клиенту.

Это, как говорится, я имею дело с этим все время, и, к сожалению, я не нашел простого решения. Вам нужно сделать проверку с обеих сторон, но вам не нужно делать ВСЮ проверку на них обоих.

Что я делаю, это пытаюсь сбалансировать его. На стороне клиента вы делаете большую часть простой (но ценной) проверки, обычные вещи, числа должны быть числами, даты должны быть датами, данные в пределах диапазона и т. д., Поэтому, когда вы отправляете его, он идет на сервер, чтобы получить полную проверку, но вы убедитесь, на стороне клиента, что большая часть информации, по крайней мере, в правильном формате, и некоторые (или большинство) из них, его уже проверены, однако, реальная бизнес-логика делается на стороне сервера, но так как большая часть данных уже правильная, проверка на стороне сервера, скорее всего, одобрит запрос, поэтому вы избежите много повторных отправок.

теперь, как сделать так, чтобы, когда вам нужно что-то изменить, вам не нужно чтобы изменить его с обеих сторон? Ну, иногда вы не сможете избежать этого, когда требуются серьезные изменения, но параметры бизнес-логики могут быть общими, и, как вы предложили, это можно сделать через ajax. Вы делаете php файл, где у вас есть все ваши параметры бизнес-логики, и с запросом ajax вы загружаете это на стороне клиента, только один раз (когда скрипт загружен), вам нужно оптимизировать это, поэтому вы получаете только значения параметров, все остальное уже должно быть на клиенте сторона, поэтому, если какое-то значение параметра в бизнес-логике изменяется, вы изменяете его только в файле параметров. (Если параметр изменяется после загрузки скрипта, проверка завершится ошибкой на стороне сервера, теперь вам нужно решить, заставляете ли вы их загружать скрипт reaload, поэтому параметры realodaded или нет, я заставляю их перезагружать их)

Я думаю, вы поняли идею. Это то, что я делаю, и это работает довольно хорошо для меня, экономит мне много перекодировки.

Я надеюсь, вы найдете это полезный.


сегодня решение явно одно из @ParthaSarathiGhosh, но ближайшее будущее, безусловно, даст нам другое решение...

WebAssembly - это язык сборки низкого уровня, который можно развернуть с помощью приложения и запустить в браузере. Это позволит вам запросить некоторую логику из JavaScript, вызвав скомпилированный код в сборке. Это рекомендуется для тяжелых сценариев, которые выполняются на стороне клиента, но в то же время позволяют повторно использовать код бэкэнда спереди. Таким образом, Вы сможете написать свою логику для серверной части, и использовать его в передней.

сегодня эта технология уже поддерживается в большинстве современных браузеров, но она доступна только с c/C++. Таким образом, вы уже можете использовать его, если у вас есть эти навыки.

Это, безусловно, планируется расширить его на другой язык также (как уже есть некоторые исследования для c# - ex:blazor - и другие языки). Но зрелость уровень кажется недостаточно стабильным для производства (даже команда разработчиков blazor еще не рекомендует его для производства).

Это только мое собственное мнение, но => логика в NodeJS-это решение для повторного использования кода javascript, но я все еще чувствую потребность в строго типизированном языке, когда дело доходит до большого поддерживаемого логического кода. (Да, я знаю TypeScript, и это действительно хорошо, но я что-то пропустил). WebAssembly все еще немного молод, но наверняка принесет большое улучшение, чтобы уважать сухой основа.