2015-09-29 3 views
2

Для проектирования и создания RESTful API следующий вопрос возникает:RESTful API Design: PUT или POST для создания отношений «многие ко многим»?

Этот API поддерживает GET (для запросов), POST (для создания), PUT (для обновления) и DELETE (для удаления).

Давайте предположим, что в базе данных мы имеем статью и магазин как уже существующий.

Теперь нам нужен звонок для подключения экземпляра статьи к экземпляру магазина. Какие из следующих решений является лучшим/наиболее чистый дизайн REST:

  1. /магазин/идентификатор/статьи/идентификатор/-> с POST
  2. /магазин/идентификатор/статьи/ID/-> с PUT
  3. /shoparticlerelation/-> с POST (объект с идентификаторами в организме)
  4. /shoparticlerelation/-> с PUT (объект с идентификаторами в организме)

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

+1

Какова связь между статьями и магазинами в простом английском? –

+0

Несколько магазинов и несколько статей - каждая статья может быть продана в каждом магазине, но только если она подключена. – Blackbam

ответ

3

Предполагаю, что в этой ситуации у вас уже есть коллекция shop s и коллекция article s, и вы просто хотите связать два вместе.

Один из вариантов, чтобы выставить более децибел, как «ресурс», который представляет эту связь, и есть такие операции, как

POST /shopArticleLinks HTTP/1.1 

{ "shop" : xxx, 
    "article: YYY 
} 

Я лично смотрю, чтобы выставить его в качестве собственности магазинов и/или изделий, в более естественное поместье, как

PUT /shop/<ID> HTTP/1.1 

{ /* existing details */ 
    "articles": [ /* list of articles */ ] 
} 

Я использовал JSON, но использование конечно, что когда-либо формат, который вы хотите использовать. Я также придерживался использования PUT, как вы заявили, но имейте в виду, что с PUT вы должны отправить полную замену новой модифицированной версии, PATCH можно использовать для отправки частичных обновлений, но тогда вам нужно подумать о том, как вы хотите сделать что может что-то вроде

PATCH /shops/<ID>/articleLinks HTTP/1.1 

{ "add" : [], 
    "remove : [] 
} 

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


Дополнительные мысли

Что касается второго способа, где вы обнажить ссылку как свойство shop и/или article ресурсов. Имейте в виду, что вполне приемлемо (и в этом случае довольно уместно), что при обновлении ссылок в данном shop ссылки обновляются в соответствующих articles.

+0

Это звучит жизнеспособно, но создание нового ресурса только для того, чтобы связать 2 других - это шаг на пути к тому, что шаблоны дизайна называют «взрывом класса» * –

+0

Да, это определенно не тот вариант, с которым я бы пошел. Он отражает то, как он скорее всего будет храниться в БД, но это игнорирует «REpresentational» часть REST: P – thecoshman

2

/shop/id/article/id/

Вы не можете использовать это, потому что в данный момент вы хотите, чтобы связать их, это конечная точка нет (или, по крайней мере, не должны) еще существуют. Это действие, связывающее их вместе, должно определять эту конечную точку.

/shoparticlerelation/

Вы не должны использовать это, потому что shoparticlerelation не является ресурсом/субъект. Обычно с отдыхом каждый сегмент URL-адреса представляет собой ресурс, который может быть CRUD-ed. /shops - хороший пример, поэтому /articles, но этого нет.


Я предлагаю следующее:

Определить следующие конечные точки

/shops для размещения новых магазинов
/shops/id для работы на одном магазине
/articles для размещения новых статей
/articles/id для эксплуатации по отдельной статье

Затем, чтобы связать их вместе, вы можете сделать так называемый запрос PATCH, чтобы обновлять статьи в магазине, либо статью, в магазины:

PATCH /shops/1 HTTP/1.1 

{ 
    "attribute": "articles", 
    "operation": "add", 
    "value": "8" // the article id 
} 

и

PATCH /articles/9 HTTP/1.1 

{ 
    "attribute": "shops", 
    "operation": "add", 
    "value": "1" // the shop id 
} 

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

Запрос PATCH используется для изменения существующего ресурса путем указания способа и обновления. Это отличается от PUT, потому что PUT заменяет весь ресурс на значения из запроса, однако PATCH используется только для изменения (не замены) ресурса.

+0

Я бы добавил +1 для вас, предлагая PATCH, но он отменяется, используя два запроса для одного действия. – thecoshman

+0

@ thecoshman Я предложил два способа связать их здесь с двумя запросами на исправления. Я бы, вероятно, связал их в обоих направлениях в одном запросе, независимо от того, через какой ресурс вы исправляете. –

+0

А я вижу, в основном то, что я предлагал, просто не так явно. – thecoshman