Чистый способ создания нескольких ресурсов (разных типов) с помощью API - PullRequest
0 голосов
/ 30 октября 2019

Для разработки API мы хотим создать новую организацию и нового пользователя для этой организации с одной отправкой формы (регистрацией) с использованием чистого дизайна RESTful API.

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

Но если создание пользователя и организации разделено на два независимых вызова API, мы видим следующие проблемы:

  1. Как обрабатывать ошибки? Например. если организация создания успешна, но создать пользователя не удается из-за ошибки (например, электронная почта пользователя уже существует). В этом случае создается организация без какого-либо пользователя, и никто не может войти в систему, чтобы изменить ресурс организации.
  2. Как обрабатывать авторизацию после создания организации? Может ли каждый с идентификатором организации просто создать нового пользователя без какой-либо проверки входа (вход возможен только с электронной почтой и паролем)? Или организация create вернет токен для создания первого пользователя? (Логика токенов сделает клиента довольно сложным: как обрабатывать повторные представления и т. Д.)

1 Ответ

0 голосов
/ 30 октября 2019

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

За исключением PATCH , ни один из стандартных методов HTTP на самом деле не справляется с транзакционным поведением. PATCH т.е. требует, чтобы все этапы команд, определенные в документе исправления, были обработаны атомарно. Либо все, либо ни один из них не должен применяться. Таким образом, если одна инструкция не выполняется, никакие модификации не должны применяться. Разница между PATCH и другими методами заключается в том, что PATCH должен содержать набор инструкций для применения к одному или нескольким ресурсам, в то время как другая операция в определенном смысле обычно предназначена для одного документа.

Если смотреть из системы управления документами, в которой HTTP действительно лежит, поскольку любые бизнес-правила, которые вы заключаете, являются лишь побочным эффектом управления документами (см. этот замечательный доклад ),операции HTTP имеют немного больше смысла. Т.е. PUT заменяет текущий документ на предоставленный. Если его еще не было, это похоже на создание документа. В спецификации здесь упоминается, что PUT может иметь побочные эффекты. То есть похоже на GIT, где коммит будет продвигать голову вперед, хотя фактический коммит все еще будет доступен через его собственный URI. DELETE удаляет связь URI с сохраненным документом. Приводит ли это к удалению документа в воображаемой файловой системе или нет - это деталь реализации. GET будет только возвращать содержимое этого документа вызывающему, а POST обрабатывает запрос только в соответствии с собственной семантикой службы, не давая никаких дальнейших обещаний относительно того, что он делает с полезной нагрузкой. Таким образом, независимо от того, создан ли один или несколько ресурсов, или даже вообще нет, зависит от реализации. Однако, если вы создаете ресурсы, вам нужно вернуть ответ 201 Created, содержащий заголовок Location с URI вновь созданного ресурса, который намекает клиентам о вновь созданном ресурсе. В случае создания нескольких ресурсов спецификация немного менее ясна, что должно быть возвращено в этом случае, так как только один заголовок Location может появиться в пределах отвечающего .

ИспользованиеПодход на основе форм - это, безусловно, подход RESTful, так как здесь сервер обучает клиента необходимым входным данным для выполнения задачи. Клиент обычно не сильно интересуется тем, как на самом деле сервер обрабатывает и хранит данные, все, что его интересует, - это завершение своего запроса, либо успешно, либо с подсказкой о проблемах, возникших у сервера при обработке запроса.

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

Конечно, вы также можете ввести данные в одной форме и отправить их на сервер с помощью запроса POST, а затем создать соответствующие ресурсы таким образом. Какой URL возвращать в заголовке Location - это другое решение. Если основным создаваемым ресурсом является организация, для которой я бы выбрал URI организации, особенно если он позволяет перечислять определенных пользователей. Внутренне вы можете использовать транзакции, чтобы гарантировать согласованное состояние между организацией и пользователем, и в случае невозможности сделать это вы просто можете откатить транзакцию и вернуть пользователю ошибку.

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

Как обрабатывать авторизацию после создания организации? Может ли каждый с идентификатором организации просто создать нового пользователя без какой-либо проверки входа (вход возможен только с электронной почтой и паролем)? Или организация create вернет токен для создания первого пользователя? (Логика токенов сделает клиента довольно сложным: как обрабатывать повторные представления и т. Д.)

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

Если у вас есть разделенный подход к организации и созданию пользователя и вы столкнулись с проблемой при создании пользователя, вы можете отправить клиенту форму с запросом других данных пользователя, так как она уже существует для другой организации, пока не будут возвращены действительные данные,Множество веб-интерфейсов API в настоящее время отправляют некоторые ссылки для подтверждения по электронной почте, чтобы проверить правильность адреса электронной почты, и пользователь только «вошел в систему» ​​в первый раз, когда он щелкнул ссылку активации в этом письме. В чистом HTTP вы бы отправили заголовок HTTP Authorization, содержащий учетные данные пользователя. В случае отсутствия активированного пользователя сервис вернет 401 Unauthorized как сбой, препятствующий аутентификации пользователя в сервисе. В таком случае внешний административный объект (т. Е. Менеджер проекта или администратор API) должен будет создать пользователя для этой организации и отправить данные запрашивающей стороне. Хотя, такого состояния следует избегать IMO. В данном случае, поиск пользователя на предмет допустимых пользовательских данных, безусловно, предпочтительнее.

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

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

Последнее замечание о предмете, упомянутом в вашем названии. Клиенты REST не должны рассматривать ресурсы определенного типа, поскольку это приводит к тому, что клиенты ожидают, что определенные конечные точки вернут определенные типы . Это также приводит к тому, что клиенты интерпретируют URI для определения типа этого ресурса. Поскольку сервер может изменять свою схему URI в любое время, когда ему это нужно, есть вероятность, что клиенты не смогут автоматически определять тип на основе URI без того, чтобы разработчик встраивал эти знания в клиента. Это позволяет избежать реальных преимуществ, которые должна обеспечить архитектура REST, а именно свободы эволюции в будущем, которая обеспечивается за счет отделения клиентов от серверов. Вместо использования типизированных ресурсов клиенты должны полагаться на согласование типа контента, когда обмениваются стандартизированные форматы представления, понятные и поддерживаемые как клиентом, так и сервером. Типы мультимедиа, определяющие эти форматы представления, задают правила обработки и семантику каждого из элементов в полезной нагрузке и обеспечивают совместимость.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...