Управление проверками на стороне клиента и на стороне сервера в одном месте

17

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

Однако в рамках и средах, в которых я работал, подходы, которые я видел, никогда не были СУХОЙ. В большинстве случаев нет плана или шаблона - проверки записываются в спецификации модели, а проверки записываются в форме в представлении. (Примечание: большая часть моего личного опыта связана с Rails, Sinatra и PHP с jQuery)

Обдумывая это, кажется, что не составит труда создать генератор, который, учитывая набор проверок (например, имя модели, поле (я), условие), мог бы производить как необходимый материал на стороне клиента, так и на стороне сервера. Альтернативно, такой инструмент может принимать проверки на стороне сервера (такие как validatesкод в модели ActiveRecord) и генерировать проверки на стороне клиента (такие как плагины jQuery, которые затем будут применяться к форме.

Очевидно, что вышеизложенное - это просто размышление «эй, у меня была эта идея», а не формальное предложение. Подобные вещи, безусловно, сложнее, чем казалось, когда идея пришла мне в голову.

Это подводит меня к вопросу: как бы вы подошли к разработке метода «один раз, запустите на сервере и на клиенте» для проверки данных?

Связанные подтемы: существуют ли подобные инструменты для каких-либо конкретных сред или технологий клиент-сервер? Каковы основные недостатки или проблемы с попыткой сохранить только один набор проверок?

asfallows
источник

Ответы:

6

По моему ограниченному опыту, пункты, где требуется проверка являются

  1. Уровень представления с использованием HTML,
  2. на уровне после презентации (т. е. проверка Javascript),
  3. на уровне комбинации, где взаимодействия между несколькими полями должны быть проверены вместе,
  4. на уровне бизнес-логики и
  5. на уровне базы данных.

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

Связанная концепция заключается в том, что представление данных варьируется между каждым из уровней. Простой пример - веб-браузер представляет фрагмент текста как, возможно, CP1290, в то время как база данных представляет его в UTF-8; длины двух строк различаются, поэтому применение ограничений длины становится неудобным.

BobDalgleish
источник
да, разные языки и структуры делают это непрактичным. Не «отменяемый», потому что с достаточным количеством ресурсов это можно сделать, но написание автоконвертеров на языки и между ними является ОГРОМНОЙ задачей. Выполнение этого в разумные сроки, а затем поддержание его по мере изменения соответствующих технологий было бы большой работой.
Майкл Даррант
Совершенно верно, что многие проверки на стороне сервера (например, уникальность поля) не могут быть выполнены в браузере. Однако также верно, что любые проверки на стороне клиента должны повторяться на сервере, поскольку вы не можете доверять клиенту. Вот где я вижу, что СУШКА становится особенно полезной. Например, я мог видеть драгоценный камень, который расширяет Rails, form_forчтобы автоматически предоставлять код проверки на стороне клиента, очень полезный.
Дан,
5

Одним из соображений, которое часто ограничивает решения, является круговая передача по сети. Клиент должен проверять пользовательские данные, не отправляя сообщение по сети. Другими словами, когда пользователь нажимает кнопку отправки, клиент должен проверять данные локально.

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

СУХОЙ, но не без недостатков. Во-первых, это зависит от того, что наш сервер облагает налогом проверки, которые могли быть обработаны на стороне клиента. Во-вторых, проект предполагает, что все операции CRUD будут выполняться через наши конечные точки, но как быть, когда разработчики и процессы обходят наш уровень доступа к данным, обращаясь непосредственно к базе данных ?

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

{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']}

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

Марио Т. Ланца
источник
Как вы описываете поле, когда поле по-разному представлено в веб-браузере, на транспорте, языке реализации и в базе данных? Например, количество байтов, необходимое для представления строкового поля, варьируется при использовании CP1290 (IE), UTF-8 (JSON), UTF-8 (C #) или UCS-16 (Oracle). Что означает ограничение длины? Что более важно для браузера, когда представление символов зависит от браузера и операционной системы?
BobDalgleish
Эти ограничения нацелены как ментальная модель на людей. Ваша работа как программиста состоит в том, чтобы абстрагироваться от различий с машиной, чтобы человеку не приходилось заботиться о технических различиях.
Марио Т. Ланца
Вы полностью упустили суть. До сих пор никто не представил абстракцию, которая допускает валидацию от начала до конца, с одной спецификацией. Из OP «написать один раз» подразумевает, что наличие разных предложений, относящихся к разным этапам, не подходит. Точно так же я не вижу ничего в предложенной вами проверке, которая касается межполевой или межобъектной проверки.
BobDalgleish
Межполевые / объектные проверки не очень сложны. Метаданные просто представляют отношения. Запись один раз подразумевает, что я пишу одну проверку один раз и применяю ее на нескольких сайтах, что и происходит. Вы добавляете метаданные в таблицу. Эти метаданные принимаются любым сайтом, и простой класс / утилита / движок применяет ограничение.
Марио Т. Ланца
1
Такой язык проверки был бы чрезвычайно полезен. Он может заменить, возможно, треть кода, используемого в интенсивных веб-приложениях.
BobDalgleish
2

Один из способов - использовать один и тот же язык / структуру как на стороне сервера, так и на стороне клиента.

Например

Node.js :: Клиент / Сервер в JavaScript GET :: Клиент / Сервер в Java

В этом случае большая часть кода «объекта домена» будет обычной, что будет включать проверку. Framework будет вызывать код по мере необходимости. Например, один и тот же код будет вызываться в браузере до «отправки» и на веб-службе на стороне сервера.

РЕДАКТИРОВАТЬ (июнь / 2014): С Java 8 теперь легко интегрировать проверочный код JS также в приложения Java. В Java 8 появился новый механизм выполнения JS, который стал более постоянным (например, он использует invokeDynamic).

Шамит Верма
источник
Когда дело доходит до базы данных SQL, не уверен, как это будет работать.
Майкл Даррант
Это также не решает проблему того, что браузер и операционная система влияют на домен ввода.
BobDalgleish
@Micheal Durrant, для проверки базы данных реализованы в виде ограничений БД (таких как внешний ключ, уникальный и т. Д.). BobDalgleish, 1. Проблема совместимости браузера и ОС может быть смягчена с помощью библиотеки, которая настраивает время выполнения в соответствии с браузером (например, Sencha) 2. Совместимость браузера, как правило, не влияет на «логические» части кода, такие как проверка, проблемы совместимости обычно вокруг DOM / UI рендеринга.
Шамит Верма
0

Я просто думал о той же проблеме. Я думал об использовании ANTLR для получения абстрактного синтаксического дерева в C # и javascript. Оттуда вы используете обходчики деревьев, чтобы применить действия, указанные на языке, к проверяемым объектам.

Таким образом, вы можете хранить описание необходимой проверки в любом месте - возможно, в базе данных.

Вот как я бы подошел к проблеме.

Маркус
источник