Я разрабатываю прагматичный REST API и немного застрял в том, как лучше всего добавить существующие сущности в коллекцию. Моя модель домена включает в себя проект, который имеет коллекцию сайтов. Это строгое отношение «многие ко многим», и мне не нужно создавать сущность, которая явно моделирует отношение (например, ProjectSite).
Мой API позволит потребителям добавлять существующий сайт в проект. Я зациклен на том, что мне нужны только данные ProjectId и SiteId. Моя первоначальная идея была:
1. POST myapi/projects/{projectId}/sites/{siteId}
Но я тоже думал о
2. POST myapi/projects/{projectId}/sites
с объектом Site, отправленным как контент JSON.
Вариант 1 прост и работает, но не совсем правильно, и у меня есть другие отношения, которые не могут следовать этому шаблону, поэтому он добавляет непоследовательность в мой API.
Вариант 2 чувствует себя лучше, но приводит к двум проблемам:
- Должен ли я создать сайт или выдать исключение, если новый сайт опубликован (SiteId = 0)?
- Поскольку мне нужны только ProjectId и SiteId для создания отношения, сайт может быть опубликован с неверными или отсутствующими данными для других свойств.
Третий вариант - предоставить простую конечную точку исключительно для создания и удаления отношений. Эта конечная точка будет ожидать полезной нагрузки JSON, содержащей только ProjectId и SiteId.
Что вы думаете?
источник
Ответы:
POST - это глагол «добавление», а также глагол «обработка». PUT - это глагол «создать / обновить» (для известных идентификаторов), и он выглядит почти как правильный выбор, потому что известен полный целевой URI.
projectId
иsiteId
уже существует, так что вам не нужно "POST в коллекцию", чтобы создать новый идентификатор.Проблема с PUT заключается в том, что тело должно быть представлением ресурса, который вы PUTting. Но цель здесь - добавить ресурс коллекции проекта / сайтов, а не обновлять ресурс сайта.
Что, если кто-то помещает полное JSON-представление существующего сайта? Стоит ли обновлять коллекцию и обновлять объект? Вы могли бы поддержать это, но похоже, что это не цель. Как вы сказали,
Скорее, я бы попробовал поместить POST в
siteId
коллекцию и полагаться на «добавление» и «процесс» природы POST:Поскольку вы изменяете ресурс семейства сайтов, а не ресурс сайта , вам нужен именно этот URI. POST может знать «добавить / обработать» и добавить элемент с этим идентификатором в семейство сайтов проекта.
Это по-прежнему оставляет открытой возможность для создания совершенно новых сайтов для проекта, уточняя JSON и опуская идентификатор. "Нет идентификатора" == "создать с нуля". Но если URI коллекции получает идентификатор и ничего больше, становится ясно, что должно произойти.
Интересный вопрос. :)
источник
POST
вместоPUT
илиPATCH
здесь, заключается в том, что у вас нет всейSite
сущности, которую нужно поместить вsites
ресурс. У вас есть только идентификатор, который требует обработки, чтобы добавить его в коллекцию.Мы используем
Patch
метод для таких вещей, как это. Что вы хотите сделать, это изменить существующий проект, чтобы добавить сайт к нему.Так что-то вроде этого будет работать
с сущностью Site (s) как JSON / JSONArray в теле запроса.
Таким образом, вы можете использовать один и тот же URL-адрес для изменения различных частей проекта, если вам нужно - ваш код в реализации должен быть достаточно интеллектуальным, чтобы справиться с этой частичной модификацией ресурса.
источник
{"sites": [], "other-stuff": {}}
, вы можете затем ветвить свой код, чтобы очень легко обрабатывать все эти "подзоны". Это действительно зависит от вашей конкретной проблемы, но я все равно рекомендую использовать PATCH, так как он разработан специально для такого рода вещей.PATCH
также не следует ожидать, что здесь будет передана полная сущность, а не идентификатор, указывающий на какую-то сущность?