Спокойный способ отправки предупреждающего сообщения Pre-Post или Pre-Put - PullRequest
3 голосов
/ 16 июня 2020

Я пытаюсь преобразовать устаревшее приложение в веб-службы Restful. Одна из наших старых форм отображала предупреждающее сообщение сразу при загрузке формы. Это предупреждающее сообщение зависит от свойства пользователя.

Например, если есть свойство isInactiveByDefault , которое, когда установлено значение «true», установит статус вновь созданного сотрудника через POST v1/employees в "Неактивный". Пользователь при загрузке формы «Сотрудник» увидит предупреждающее сообщение «Любой новый созданный сотрудник будет иметь неактивный статус».

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

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

Ответы [ 2 ]

3 голосов
/ 14 июля 2020

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

Но оставим этот момент в стороне, и если мы рассмотрим сообщение (я), отображаемое как данные, то, как только ваш клиент сможет сделать REST вызовов (через JS, AJAX или что-то еще), вы должны иметь возможность запрашивать сервер до или во время загрузки формы (и ждать / синхронизировать c на этом).

Так что это прекрасно fine и "RESTful" для выполнения запроса GET к службе, т. е. получения списка предупреждений (в конечном итоге интернационализированных) и их отображения. Сервер подготовит этот список предупреждений на основе того или иного свойства и вернет его (как JSON или что-то еще). Вашему клиенту нужно будет только отобразить результат синтаксического анализа запроса (от 0 до N сообщений для списка) рядом с вашей формой.

EDIT

Пример службы REST для вашего вариант использования:

@POST
@Path("/v1/employees")
public Response someFormHandlingMethod() {
   // Your form processing
   ...
   if(EmployeeParameters.isInactiveByDefault()) {
      emp.setInactive(true);
   }
   ...
}

@GET
@Path("/v1/employees/formwarnings")
public Response getEmployeeFormWarnings() {
   // "Business logic" -> Determine warning messages to return to client
   ...
   if(EmployeeParameters.isInactiveByDefault()) {
      warnings.add("Any new employee created will have inactive status");
   }
   ...
   // and return them in Response (entity as JSON or whatever). Could also be List<String> for example.
}

Это просто пример, чтобы вы поняли идею, но фактическая реализация будет зависеть от вашей конфигурации Джерси, картографов / преобразователей, аннотаций (например, @Produces) и т. д. c.

0 голосов
/ 21 июля 2020

Основное внимание в архитектуре REST уделяется разъединению клиентов и серверов путем определения набора ограничений, которых должны придерживаться обе стороны. Если эти ограничения строго соблюдаются, это позволяет серверам свободно развиваться в будущем, не рискуя сломать клиентов, которые также придерживаются архитектуры REST, в то время как такие клиенты, как следствие, станут более устойчивыми к изменениям. Таким образом, сервер должен обучать клиентов тому, как должны выглядеть определенные вещи (например, посредством предоставления форм и элементов управления формами) и какие дальнейшие действия (например, ссылки) клиент может выполнять из текущего состояния.

Запрашивая операции Pre-Post или Pre-Put, я предполагаю, что вы уже предполагаете взаимодействие HTTP, которое довольно часто встречается в так называемых системах «RESTful». Хотя, как указал Джим Уэббер , HTTP - это просто транспортный протокол, домен приложения которого является передачей документа от источника к цели, и любые бизнес-правила, которые мы заключаем из этого взаимодействия, являются лишь побочным эффектом актуальный документооборот. Таким образом, мы должны найти способы инициировать определенные бизнес-операции на основе обработки определенных документов. Вдобавок к этому HTTP не знает ничего вроде pre-post, pre-put и т.п.

Обычно практическое правило в распределенных вычислениях - никогда не доверять никакому вводу клиента и, таким образом, проверять ввод на снова на стороне сервера. Первое решение для проверки работало на сервере, предоставляя клиенту веб-форму , которая обучает клиентов доступным свойствам ресурса, а также предоставляет клиентам набор элементов управления вводом для взаимодействия с этой формой (т. Е. Отправка кнопка, которая при нажатии будет упорядочивать входные данные в формат представления, который отправляется с помощью операции HTTP, поддерживаемой сервером). Таким образом, клиенту не нужно было знать какие-либо внутренние устройства сервера, поскольку ему была предоставлена ​​вся информация, необходимая для составления следующего запроса. В этом суть HATEOAS. Как только сервер получил запрос на определенную конечную точку, он начал обрабатывать полученный документ, то есть входные данные, и если определенные ограничения, которые он наложил на этот ресурс, были нарушены, он в основном отправлял ту же форму, что и раньше, клиенту, хотя на этот раз с включены входные данные клиента и дополнительная разметка, которая была добавлена ​​в представление формы, указывающее на ошибку ввода. За счет атрибутов стиля, добавленных к этим ошибкам, они обычно заметно выделялись из общего дизайна страницы (обычно красный текст и / или поле рядом с элементом управления вводом, вызывающим нарушение) и, таким образом, позволяли упростить обработку проблем.

С введением JavaScript некоторые умные люди придумали способ не только отправлять форму клиенту, но и скрипт, который автоматически проверяет ввод данных пользователем в фоновом режиме и, в случае нарушения, динамически добавляет вышеупомянутую разметку ошибок в DOM текущей формы / страницы и таким образом информирует пользователя о возможных проблемах с текущим вводом. Однако для этого требуется, чтобы текущий формат представления или более формально его медиа-тип поддерживал динамическое c содержимое, такое как сценарии и манипулирование текущим форматом представления.

К сожалению, многие форматы представления обмениваются в типичном "REST" API / сервисы »не поддерживают такие свойства. Обычный документ JSON, т.е. просто определяет базовый синтаксис c (т.е. объекты являются контейнерами ключ-значение между фигурными скобками, ...), но он не определяет семантику ни для одного из полей, которые он может содержать, он определяет даже не знаю, что такое URI и тому подобное. Таким образом, JSON не подходит для начала в архитектуре REST. Хотя HAL / JSON или JSON Hyper-Schema пытаются добавить поддержку ссылок и рудиментарной семантики, они все же создают свои собственные медиа-типы и, следовательно, форматы представления. Другие типы носителей на основе JSON, такие как hal-forms , halo + json (halform) и ion , попытайтесь добавить поддержку форм. Некоторые из этих форматов мультимедийных типов могут позволять добавлять ограничения к определенным элементам формы, которые автоматически заканчиваются предупреждением пользователя и блокировкой фактической передачи документа в случае нарушения, хотя большинство текущих типов мультимедиа могут еще не поддерживать клиентский интерфейс. сторонние скрипты или динамические c обновления содержимого.

Такие обстоятельства приводят Филдинга в одном из его известных сообщений в блоге к следующему утверждению:

ОТДЫХ API должен тратить почти все свои описательные усилия на определение типа (ов) мультимедиа, используемого для представления ресурсов и управления состоянием приложения, или на определение расширенных имен отношений и / или гипертекстовой разметки для существующих стандартных типов мультимедиа

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

Что касается решения «RESTful», я бы не рекомендуется использовать настраиваемые заголовки или проприетарные форматы сообщений, поскольку они обычно понятны и, следовательно, могут обрабатываться только ограниченным количеством клиентов, что является противоположностью тому, чего на самом деле стремится достичь архитектура REST. Такие сообщения обычно также требуют априорных знаний о поведении сервера, что может привести к проблемам, если сервер когда-либо потребуется изменить.

Итак, короче говоря, по сути, самый безопасный способ ввести "RESTful" (~ one это соответствует ограничениям, установленным архитектурой REST) ​​проверка ввода для ресурса осуществляется с использованием представления на основе формы, которое учит клиента всему, что ему нужно для создания фактического запроса, где запрос обрабатывается сервером и если определенные ограничения ввода подтверждены, приводит к повторному возврату формы клиенту с подсказкой о соответствующей проблеме ввода.

Если вы хотите минимизировать взаимодействие между клиентом и сервером из-за соображений производительности (которые обычно не основная проблема) вам может потребоваться определить свой собственный тип мультимедиа, который добавляет поддержку скриптов и динамические c обновления содержимого с помощью аналогичных средств, таких как манипуляции с DOM и т.п. Однако такой настраиваемый тип носителя должен быть зарегистрирован в IANA , чтобы другие разработчики могли добавить поддержку таких типов и, таким образом, позволить другим клиентам взаимодействовать с вашей системой в будущем.

...