У якому шарі має бути розміщена перевірка?


18

Я створюю API відпочинку за допомогою Spring Boot, і я використовую Hibernate Validation для перевірки введення запиту.

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

Чи повинна ця перевірка розташовуватися на рівні обслуговування або на рівні контролера?

Службовий шар:

 public Company update(Company entity) {
    if (entity.getId() == null || repository.findOne(entity.getId()) == null) {
        throw new ResourceNotFoundException("can not update un existence data with id : " 
            + entity.getId());
    }
    return repository.saveAndFlush(entity);
}

Шар контролера:

public HttpEntity<CompanyResource> update(@Valid @RequestBody Company companyRequest) {
    Company company = companyService.getById(companyRequest.getId());
    Precondition.checkDataFound(company, 
        "Can't not find data with id : " + companyRequest.getId());

    // TODO : extract ignore properties to constant

    BeanUtils.copyProperties(companyRequest, company, "createdBy", "createdDate",
            "updatedBy", "updatedDate", "version", "markForDelete");
    Company updatedCompany = companyService.update(company);
    CompanyResource companyResource = companyAssembler.toResource(updatedCompany);
    return new ResponseEntity<CompanyResource>(companyResource, HttpStatus.OK);
}

Відповіді:


8

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

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

Один з можливих способів зробити це - розділити валідацію цього договору і запросити його в обох шарах. Зазвичай це найбільш зрозуміло - кожен клас / метод виконує свій власний контракт, але часто є непрактичним через ефективність роботи (доступ до бази даних) або з інших причин.

Інша можливість полягає в делегуванні цієї перевірки на рівень обслуговування, одночасно чітко визначаючи поведінку у разі невдалої перевірки в договорі про рівень обслуговування. Службовий рівень зазвичай повертає певну загальну помилку перевірки (або викид виключення), і рівень контролера захоче реагувати певним чином на помилку - у цьому випадку ми повернемо 400 Неправильний запит, щоб повідомити про те, що вхідний запит був недійсним.

У цьому дизайні існує небезпека занадто великого зв’язку між бізнес-логікою в рівні обслуговування (який повинен бути досить загальним) і контролером (який обробляє логіку інтеграції).

У всякому разі, це досить суперечливе питання, і 100 людей дадуть відповідь зі 100 відповідями. Це лише мій погляд на це.


1

Введення слід перевірити на рівні обслуговування.

І "Неможливо знайти ідентифікатор" - це умова логічної помилки. Тому слід викинути з шару контролера.

Це знову залежить від вашого шару / дизайну.
Що повинен робити сервісний шар і що очікується від рівня контролера.


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

"Вхідна перевірка" неоднозначна. Наприклад, я можу поставити атрибут Потрібний атрибут на поле, щоб вказати, що його потрібно заповнити, але також я можу поставити складний спеціальний атрибут, який перевіряє, наприклад, що одне значення поля більше іншого. IMHO, валідація Порівняння "пахне" набагато більше рівня обслуговування бізнес, ніж рівень контролера.
JustAMartin

1

Перевірка в сплячому режимі - це перевірка цілісності даних. Щоб уникнути RuntimeExceptions від bbdd. Вони майже однакові перевірки, які слід контролювати за допомогою обмежень . Оскільки лише бізнес-шар повинен живити шар постійності, ви можете (чи ні, залежати від вас) довіряти правильності даних, що надходять із вашого бізнес-рівня

Я не ставлю перевірки в DAO. Я очікую дійсних даних від верхніх шарів. У разі помилки я делегую bbdd відповідальність за ознайомлення з його вмістом.

Потім відбувається перевірка на рівні бізнесу. Усі перевірки бізнесу були зосереджені на збереженні узгодженості даних, а не на їх цілісності .

Нарешті я роблю попередні перевірки на контрольному шарі. Ті, що стосуються лише такого шару.

Незабаром ви побачите, які перевірки призначені для впровадження на рівні бізнесу. Найпоширеніші: контроль id. Цей може бути легко реалізований на обох шарах. Якщо ви очікуєте, що багато контролерів або клієнтів споживають ваш бізнес-рівень, то замість того, щоб повторювати однакову перевірку скрізь, це буде відмінним кандидатом, який буде розміщений на рівні бізнесу.

Іноді у контролерів є свої правила та умови, які не можуть бути відтворені на будь-якому іншому фасаді. Тоді це кандидат може бути поставлений у такий контролер.

Подумайте, для чого ви підтверджуєте, і якщо ви хочете застосувати це для всіх, незважаючи ні на що. Або якщо це контекстна перевірка ("Я перевіряю те, що відбувається лише на певному фасаді керування / перегляду").


0

У нашому магазині Java ми навмисно розділили перевірку веб-віджетів на три окремі операції.

  1. Основне форматування - числа повинні бути числами; дати повинні бути дійсними датами тощо. Зазвичай ця перевірка проводиться безкоштовно - веб-рамка зробить це за вас, прив’язуючи вміст віджетів до моделі.
  2. Одиночна перевірка віджетів - дата повинна бути в минулому; ціле число повинно бути від 1 до 100; customerId повинен існувати в базі даних тощо. Це в більшості випадків належить до рівня контролера, але може знадобитися підтримка сховища даних.
  3. Перехресне підтвердження віджетів - дата оформлення замовлення повинна бути після дати реєстрації; дата смерті не може бути до дати народження тощо. Це, безумовно, перевірка ділових правил. Ми, як правило, також поміщаємо це в рівень контролера, але ви можете переключити його на валідатор бізнесу, щоб його можна було повторно використовувати.

Якщо рівень 1 виходить з ладу, ми не перевіряємо 2 або 3. Так само, якщо 1 успішно, а 2 - не, ми не робимо 3. Це зупиняє генерування помилкових повідомлень про помилки.

Ви запитуєте про значення у виклику REST, а не про вміст віджетів, але застосовуються ті самі принципи.


-1

Тестовий похід підсвічує світло на цьому, адже регулятора немає, і ви повинні вибрати інший варіант. Очевидно, що ділові правила повинні бути в одному місці, і це ще одне обмеження у ваших рішеннях.

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