2016-01-26 10 views
1

Предположим, что у меня есть REST API, который придерживается основных принципов HATEOAS. Items относятся к User.Лучший подход для обновления отношения к другому ресурсу в REST API

GET /item/13 

{ 
    id: 13, 
    name: 'someItem', 
    type: 'someType', 

    _links: [ 
    { 
     rel: 'user', 
     href: '/user/42' 
    } 
    ]   
} 

Теперь мне нужен способ изменить пользователя для данного элемента. С помощью PUT или PATCH, который является предпочтительным способом выполнения этой модификации?

  1. Установите новое отношение, установив идентификатор нового связанного ресурса как простое свойство в теле JSON

    PATCH /item/13 
    { 
        userId: 43 
    } 
    
  2. установить новое отношение, имея клиента передать ссылку себя как вход

    PATCH /item/13 
    { 
        _links: [ 
        rel: 'user', 
        href: '/user/43' 
        ] 
    } 
    

я обычно думаю, ссылки, как только для чтения представлений отношений Типов которые хранятся в других форматах (например, id: s для других ресурсов), которые возвращаются из вызовов GET. Мне не очень удобно иметь ссылки как вход на вызовы POST/PUT/PATCH, а тот факт, что ссылки - это массив, делает его еще более странным (нужно ли обновлять все ссылки?), но я видел это в различных статьях. Есть ли наилучшая практика? Каковы преимущества использования подхода ссылок?

+1

для таких сценариев Мне всегда нравится, как GitHub использует put на дочерний ресурс при старте проекта. Я их API вы используете 'PUT' или' DELETE' на '/ project/star'. Для простых модификаций я обычно использую PUT '/ item/{ID}/user' или DELETE'/item/{ID}/user/{ID} '. Это швы не соответствуют стандартам REST, но, на мой взгляд, менее неудобно использовать, чем передавать его в основном запросе тела ресурса. – Adam

ответ

4

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

API также должен быть более наглядным. Это может быть субъективным, и я не знаю всех деталей вашей модели/дизайна, но «элементы» не имеют «ссылок». Вместо «Элементов» может быть один «владелец». Если это так, то это может выглядеть примерно так:

GET /item/123/owner 

Так размещая или Puting Адрес пользователя (или какой-то простое представление) будет «изменение» владелец пункта. Возможно, не удастся УДАЛИТЬ владельца, в зависимости от того, разрешает ли модель недопустимые элементы.

Обратите внимание, что представление в разделе «/ item/123» в этом случае должно ссылаться на «/ item/123/owner», поскольку клиент только следит за ссылками, которые он получает с сервера.

Итак, подумайте о том, какие важные «вещи», все из них должны иметь ресурс. Кроме того, попробуйте добавить как можно больше «смысла»/семантики. Отношение должно быть не называться «пользователем», его следует называть «владельцем» (или каким бы то ни было значением в вашей модели).

+0

Действительно хороший совет, спасибо, это имеет смысл. Я попытаюсь реализовать это. На самом деле, конечно, моя модель намного сложнее, чем простой пример, показанный выше. – JHH

+0

Одна вещь, которая ударяет меня, - это как обрабатывать начальные значения владельца, хотя? Если владелец * может * присутствовать уже при создании элементов, кажется, не идеально, что нужно выполнить 'POST/items', за которым следует' PUT/items/xx/owner'. – JHH

+0

В некоторых случаях необходимые отношения могут быть выражены через сам URI (например, возможно, вы не будете делать «POST/items», а «POST/users/joe/items», если знаете, что элемент изначально принадлежит Джо?) но бывают ситуации, когда это не имеет смысла, вы можете захотеть «привязать» элемент к какой-то другой сущности, кроме, например, владельца. В этом случае я не вижу другого выбора, кроме того, что у меня есть 'owner: 'joe'' inline с другими свойствами элемента в теле' POST/items'? – JHH