Керування перевірками на стороні клієнта та сервера в одному місці


17

Я на 100% працюю над тим, що, безумовно, слід використовувати як перевірку даних на стороні клієнта, так і на сервері.

Однак у рамках, в яких я працював, підходи, які я бачив, ніколи не бували сухими. У більшості випадків немає плану чи шаблону - перевірки записуються у специфікації моделі, а перевірки записуються у формі на поданні. (Примітка. Більшість мого досвіду з перших рук - це Rails, Sinatra та PHP w / jQuery)

Придумуючи це, схоже, було б не важко створити генератор, який, з урахуванням набору валідацій (наприклад, назва моделі, поля (и), умова), міг би створити необхідний матеріал на стороні клієнта та на сервері. Крім того, такий інструмент може приймати перевірки на стороні сервера (наприклад, validatesкод у моделі ActiveRecord) та генерувати перевірки на стороні клієнта (наприклад, плагіни jQuery, які потім будуть застосовані до форми.

Очевидно, що вище сказане - це просто місінг, "я мав цю ідею", а не формальна пропозиція. Такі речі, безумовно, складніше, ніж здавалося, коли ідея мене вразила.

Це підштовхує мене до питання: як би ви підходили до проектування методики "один раз, запустіть на сервері та клієнті" для перевірки даних?

Пов'язані підтеми: Чи існують такі інструменти для будь-яких конкретних рамок або технологій клієнт-сервер? Які основні проблеми та проблеми, коли намагаються підтримувати лише один набір перевірок?

Відповіді:


6

За моїм обмеженим досвідом, точки, де необхідна перевірка, є

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

Кожна з них має різні мови, терміни та тригери. Наприклад, мало сенсу перевірити поле до того, як весь запис буде у стані, якщо ви не хочете перевірити лише один фрагмент. Обмеження на рівні бази даних повинні бути застосовані лише наприкінці перед фіксацією, і їх не можна легко виконати детально.

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


Так, різні мови та рамки роблять це непрактичним. Не є "невідмінним", оскільки з достатньою кількістю ресурсів це можна зробити, але написання автоматичних перетворювачів на та між мовами - це ВЕЛИЧЕЗНА завдання. Робити це в розумні часові рамки, а потім підтримувати їх у міру зміни відповідних технологій було б багато роботи.
Майкл Дюрант

Безумовно, правда, що багато перевірок на стороні сервера (наприклад, унікальність поля) неможливо виконати в браузері. Однак також вірно, що будь-які перевірки на стороні клієнта потрібно повторити на сервері, оскільки ви не можете довіряти клієнту. Ось де я бачу, як СУХАЛИ речі особливо корисні. Наприклад, я міг побачити дорогоцінний камінь, який розширює 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

Ці обмеження спрямовані як ментальна модель на людину. Ваше завдання програміста полягає в тому, щоб абстрагувати відмінності від машини, щоб людині не було байдуже про якісь технічні відмінності.
Маріо Т. Ланза

Ви повністю пропустили пункт. Поки ніхто не представив абстракцію, яка дозволяє перевірити від кінця до кінця, з однією специфікацією. З ОП "писати один раз" випливає, що наявність різних застережень, що стосуються різних етапів, не підлягає визначенню. Так само я не бачу нічого у запропонованій валідації, що стосується міжпольової чи інтеробневої перевірки.
BobDalgleish

Перевірка між полями / об'єктами не є великою частиною. Метадані просто представляють взаємозв'язок. Один раз записувати означає, що я один раз записую одну перевірку і застосовую її на кількох сайтах, що це і робить. Ви додаєте метадані до таблиці. Ці метадані отримує будь-який сайт, а простий клас / утиліта / двигун виконує обмеження.
Маріо Т. Ланза

1
Така мова перевірки була б надзвичайно корисною. Він міг би замінити, можливо, третину коду, який стосується інтерактивних веб-додатків.
BobDalgleish

2

Одним із способів було б використання однієї мови / основи як на сервері, так і на стороні клієнта.

Напр

Node.js :: Клієнт / Сервер у JavaScript GET :: Клієнт / Сервер на Java

У цьому випадку більша частина коду "Об'єкт домену" була б загальною, яка включала б перевірку. Framework буде викликати код у міру необхідності. Наприклад, той самий код буде викликатись у браузері перед "надіслати" та на веб-службі на стороні сервера.

EDIT (червень / 2014): З Java 8 тепер легко інтегрувати код перевірки JS і в додатки Java. У Java 8 є новий механізм виконання JS, який є більш постійним (наприклад: він використовує invokeDynamic).


Якщо мова заходить про базу даних SQL, не знайте, як це буде працювати.
Майкл Дюррант

Це також не вирішує питання про те, що браузер і операційна система впливають на вхідний домен.
BobDalgleish

@Micheal Durrant, для перевірки баз даних реалізовано як обмеження БД (наприклад, зовнішній ключ, унікальний тощо). BobDalgleish, 1. Випуск сумісності браузера та ОС можна пом'якшити, використовуючи бібліотеку, яка налаштовує час виконання відповідно до браузера (наприклад, Sencha). навколо рендерингу DOM / інтерфейсу користувача
Шаміт Верма

0

Я просто думав над тією ж проблемою. Я думав використовувати ANTLR для отримання абстрактного синтаксичного дерева як у C #, так і в JavaScript. Звідти ви використовуєте крокуючі дерева, щоб застосувати дії, визначені мовою, до об'єктів, які слід перевірити.

Тоді ви можете зберігати опис необхідної перевірки, де завгодно - можливо, у базі даних.

Ось як я підходив би до проблеми.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.