RESTful API с лучшими практиками ассоциаций

#java #rest

Вопрос:

Мы реализуем API RESTful, и у нас есть запрос POST, который выглядит так /v1/systems/{systemId}/subsystems , а тело выглядит так {"id": 0, "systemId": 0, "name": "string"} . Является ли это дублированием переменных? Это хорошая практика, чтобы все было так?

Комментарии:

1. Для меня да, это дубликат, почему вы хотите иметь systemId как переменную пути, так и тело? Почему ты не можешь им воспользоваться?

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

3. Переменная path необходима для метода GET. systemId От тела присутствует, потому что в DTO оно у нас есть, и оно также сопоставлено с телом ответа/запроса.

Ответ №1:

URI в целом является идентификатором ресурса, а не только его последней части. Независимо от того, соответствует ли сам URI какому-либо структурному дизайну или нет, также зависит от ваших проектных решений. Сам по себе URI, подобный .../systems/{systemId}/subsystems , не обязательно указывает, что он является частью systems коллекции с родительским ресурсом, идентифицированным соответствующим systemId . Это «развивается» только в том случае, если клиент естественным образом исследует URI, которые в общей сложности охватывают дерево, в котором строится эта связь. Хотя такие отношения обычно выражаются отношениями ссылок, такими как up ссылка на родительский ресурс и item для определенного элемента в коллекции, subsection для части ресурса коллекции и так далее. Посмотрите в реестре связей Iana, доступны ли связи, соответствующие вашим потребностям. Если ни одно из доступных отношений ссылок не соответствует вашим потребностям, вы можете либо зарегистрировать новые в Iana, либо использовать расширения отношений веб-ссылок, в которых вы можете определять частные отношения в своем собственном пространстве имен.

Что касается добавления systemId в тело, когда вы используете структуру URI, где systemId она уже используется в пути для идентификации родительского ресурса, эта информация тогда явно избыточна. Но хотите ли вы по-прежнему включать его в полезную нагрузку-это ваш дизайнерский выбор. Нет ничего плохого в том, чтобы включить его или исключить.

К сожалению, информация на subsystems ресурсе довольно ограничена. Текущая полезная нагрузка, указанная потенциально, может быть сведена к самому имени, поскольку systemId оно указано в URI, а id ресурс подсистемы может быть сгенерирован автоматически и не определен клиентом. Таким образом, полезная нагрузка будет сведена к одному имени. Здесь вы также можете избежать создания всего подресурса и смоделировать имя подсистемы в самой system записи, спроектировав ее как массив имен. Здесь вместо создания подресурса вы можете просто предоставить метод обновления системного ресурса (с помощью исправления), чтобы добавить имя в этот массив. Но опять же, это ваш дизайн. Все, что работает для вас, здесь прекрасно.

Как правило, следует ли включать такую информацию в полезную нагрузку или нет, вы можете взять в качестве примера Веб. Т. Е. если идентификатор должен быть частью представления для представления конечному пользователю, введите его. Если нет, оставьте это в стороне. Подумайте о продукте, который вы хотите отобразить на странице. Иногда может быть полезно, если присутствует соответствующий идентификатор продукта, если вы хотите предоставить клиенту уникальный способ обращения к этому конкретному продукту в случае претензий или вопросов. Однако, поскольку идентификаторы ресурсов не должны изменяться, если это возможно, было бы более полезно предоставить UUID в качестве внутреннего идентификатора продукта и использовать идентификатор продукта, который клиенты должны использовать в другом поле вместе с ним. У одного из наших клиентов однажды было слияние, и в этом слиянии они в основном объединили продукты двух компаний с разными идентификаторами в своих базах данных. Как следствие, им пришлось изменить множество URI ресурсов, хотя продукты (в их реальной форме) вообще не изменились. Таким образом, к сожалению, некоторые клиенты, которые внезапно не смогли получить доступ к описаниям продуктов с ранее размещенными закладками и т. Д., Поскольку перенаправление не было введено. Это, безусловно, экстремальная и редкая ситуация, хотя она может возникнуть, и если бы вы использовали дизайн, который поддерживает такое изменение по дизайну, влияние на всю систему было бы заметно менее драматичным.

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

Ответ №2:

Обычно для создания ресурса не публикуется URL-адрес, указывающий на один ресурс. Ваш URL-адрес выглядит более правильным для ПОЛУЧЕНИЯ, РАЗМЕЩЕНИЯ или УДАЛЕНИЯ.

Не зная ваших точных требований, можно было бы сделать:

 POST body {"systemId": 0, "name": "string"} to /v1/systems or /v1/subsystems
 

Ответ может содержать созданную подсистему вместе с новым идентификатором.