2015-03-12 9 views
4

Я основываю свой вопрос на How to handle many-to-many relationships in a RESTful API?, но хочу продолжить с принятого ответа.REST и многие для многих

Предположим, у нас есть отношения «многие-ко-многим» между игроками и командами (как в упомянутом выше вопросе).

Как я понимаю, есть несколько вариантов, чтобы смоделировать это с REST ресурсов:

Полезная нагрузка содержит ссылки на соответствующие ресурсы

GET /players/john 

Урожайность

{ 
    "name": "John", 
    "_links": [ 
     { 
      "rel": "team", 
      "href": "/teams/1" 
     }, 
     { 
      "rel": "team", 
      "href": "/teams/4" 
     } 
    ] 
} 

и

GET /teams/1 

дает

{ 
    "name": "Team 1", 
    "_links": [ 
     { 
      "rel": "player", 
      "href": "/players/john" 
     }, 
     ... 
    ] 
} 

Это заставляет меня обновлять играющим ресурс, когда я просто хочу, чтобы добавить игрока в команду. Кроме того, когда я добавляю игрока в команду с использованием ресурса игрока, соответствующий командный ресурс автоматически обновляется. По How to handle many-to-many relationships in a RESTful API?:

вы не хотите альтернативный URL/игроков/5/команды/оставаться в кэше

В этом случае команды/1 может оставаться в кэше, когда я обновляю игрока «John «удалить команду« Team 1 »из нее!

Отношения моделируется как другой ресурс

GET /teams/1 

дает

{ 
    "name": "Team 1", 
} 

и

GET /players/john 

дает

{ 
    "name": "John", 
} 

Наконец,

GET /relationships 

дает

[ 
    { 
     "_links": [ 
      { 
       "rel": "player", 
       "href": "/players/john" 
      }, 
      { 
       "rel": "team", 
       "href": "/teams/1" 
      } 
     ] 
    }, 

    ... 
] 

Таким образом, я могу создавать и удалять отношения, не затрагивая оба игрока-ресурсы и ресурсы по команде. Но когда я удаляю/players/john, должны ли автоматически совпадать отношения соответствия? Если это так, то такое же правило, как указано выше, нарушено. Если это не так, нам нужно вручную удалить эти отношения, которые являются большой работой, я не хочу обременять потребителей моего API.

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

Каждая сторона отношений получает свое собственное отношения-объект

GET /teams/1/players 

дает что-то вроде

{ 
    "_links": [ 
     { 
      "rel": "player", 
      "href": "/players/john" 
     }, 
     ... 
    ] 
} 

и

GET /players/john/teams 

что-то вроде

{ 
    "_links": [ 
     { 
      "rel": "team", 
      "href": "/teams/1" 
     }, 
     ... 
    ] 
} 

Но добавление или удаление один все еще может повлиять на ресурс, который находится в другой URL (который не разделяет корневой элемент)

Мои вопросы

Есть далеко вокруг проблем, которые я упомянули в обоих случаях?

Какой из двух подходов является «предпочтительным» или более чистым REST?

Насколько серьезно я должен принять contstraint упомянутого в How to handle many-to-many relationships in a RESTful API?:

вы не хотите альтернативный URL/игрок/5/команд/оставаться в кэше

Спасибо заранее!

+0

* Это заставляет меня обновить плеер -resource, когда я просто хочу добавить игрока в команду. * Почему это так плохо? –

+0

Например, мне нужно знать все ДРУГИЕ команды, в которых игрок находится, чтобы обновить игрока до нужного состояния (имея ВСЕ правильные отношения с командами). Кроме того, я хочу, чтобы игроки меняли команды, но я не хочу, чтобы игроки меняли свои имена. Это ответственность администратора. Оба используют один и тот же ресурс, и мне нужно проверить роли и сравнить их с запрошенными изменениями, а не просто отключить PUT или POST на ресурсе для некоторых пользователей. –

+0

* Мне нужно знать все ДРУГИЕ команды, в которых игрок находится *, почему?вы можете просто добавить команду к player.teams –

ответ

1

Вы могли бы иметь следующие

Team

GET /teams/dream 

{ 
    "_links": { 
     "self": { 
      "href": "/teams/dream" 
     } 
     "players": { 
      "href": "/players?team=dream" 
     } 
    }, 
    "name": "Dream" 
} 

игрока

GET /player/john 

{ 
    "_links": { 
     "self": { 
      "href": "/player/john" 
     }, 
     "teams": { 
      "href": "/teams?player=john" 
     }, 
    }, 
    "name": "John", 
} 

команды Джона

GET /teams?player=john 

{ 
    "_links": { 
    }, 
    "items": [ 
     { 
      "href": "/teams/a-team" 
     } 
    ], 
} 

Добавление джон помечтать команду (используя JSon патч для примера) (запрос str ING на патч посте ... и т.д., хотя редко, справедливо)

PATCH /teams?player=john 

[{ 
    "op": "add", 
    "path": "/-", 
    "value": { 
     "href": "/team/dream" 
    } 
}] 

Получить команды Джонса

GET /teams?player=john 

{ 
    "_links": { 
    }, 
    "items": [ 
     { 
      "href": "/teams/a-team" 
     }, 
     { 
      "href": "/teams/dream" 
     } 
    ] 
} 

Джона покидает команду:

PATCH /teams?player=john 

[{ 
    "op": "remove", 
    "path": "/0" 
}] 
+0

Спасибо, что нашли время ответить на мой вопрос. Есть ли причина, по которой вы используете атрибут «op» «remove» и «add» вместо использования DELETE и PATCH? И как вы УДАЛИТЕ все отношения Джона? Через/команды? User = john? –

+0

DELETE/teams? Player = john Для патча вы можете использовать любую структуру, которую хотите, но прилагаются усилия, чтобы сделать что-то стандартное для этого. См. Http://jsonpatch.com – redben

+0

Спасибо за ваш ответ. Я не знал о патче JSON, но похоже, что это может решить многие мои проблемы! –

Смежные вопросы