Каков надлежащий способ борьбы с добавлением/удалением отношений "многие ко многим" в REST?

Скажем, у нас есть сущность, которая содержит список пользователей на сервере, и мы хотим разоблачить это как отдых. Каков правильный способ сделать это?

Моя первая догадка выглядит примерно так:

/entity/1/user/5

Мы можем использовать PUT для обновлений и DELETE для удаления?

Правильно ли это? Я поехал в Википедию, где рассказывал об отдыхе, и их взгляд на то, что все только 1 уровень глубины. Так что, может быть, они хотят, чтобы вы использовали PUT/POST и передавали весь график JSON и все сразу обновляли?

Ответ 1

Ваш пример - совершенно правильный подход. Однако во многих случаях a User может существовать вне контекста только entity. Я склонен идентифицировать ресурсы в изоляции, например:

/entity/1
/user/5

Чтобы увидеть пользователей, связанных с сущностью, я буду использовать:

/entity/1/users

Добавление пользователя может быть выполнено путем POST пользователя,

POST /entity/1/users
<User>
...
</User>

Удаление пользователя будет

DELETE /User/5

Обновление или создание пользователя можно выполнить с помощью PUT

PUT /User/6

Удаление связи между пользователем и объектом требует немного творчества. Вы могли бы сделать

DELETE /Entity/1/User/5 

как вы предположили, или что-то вроде

DELETE /Entity/1/UserLink?UserId=5

или просто

DELETE /Entity/1/Users?UserId=5

Реальность не очень важна для пользователя вашего API, как выглядит ваш URI. Хорошо быть последовательным для вашего собственного здравомыслия, хорошо выбирать схемы, которые легко отправлять с вашей инфраструктурой сервера, но это не то, что выглядят ваши URI, это то, что вы делаете с ними, что важно.

Ответ 2

Я использую ваш метод для родительских/дочерних объектов, но для многих-ко-многим я использую массив в моем объекте JSON, представляющем этот объект.

Итак, используя ваш пример:

GET /entity/1

возвращает объект сущности примерно так:

{"entityID":1,"name":"whatever","users":[1,2,3,4,5]}

PUT будет проходить в этом же объекте и обновлять как объект, так и пользователей. Затем, чтобы получить конкретную информацию о пользователе:

GET /users/3

Использование PUT для пользователей /3 будет обновлять пользователя. PUT on/entity/1 будет подключать пользователей к объектам. К сожалению, не так много хорошей информации о том, как моделировать такие вещи.