2015-09-29 2 views
2

Pour la conception et la création d'une API RESTful la question suivante se produit:RESTful API Design: PUT ou POST pour créer des relations many-to-many?

L'API prend en charge GET (pour les requêtes), POST (pour la création), PUT (mises à jour) et supprimer (pour la suppression).

laisse supposer dans la base de données que nous avons un article et une boutique les deux déjà existants.

Nous avons maintenant besoin d'un appel de repos pour lier l'instance d'article à l'instance de magasin. Laquelle des solutions suivantes est le meilleur/plus propre conception REST:

  1. /boutique/id/article/id/-> avec POST
  2. /boutique/id/article/id/-> avec PUT
  3. /shoparticlerelation/-> avec POST (objet avec ids dans le corps)
  4. /shoparticlerelation/-> avec PUT (objet avec ids dans le corps)

S'il n'y a pas de réponse claire ou toutes les solutions sont également bonnes, cela peut aussi être une réponse valable s'il y a une argumentation claire pourquoi?

+1

Quelle est la relation entre les articles et les magasins en anglais? –

+0

Plusieurs boutiques et plusieurs articles - chaque article peut être vendu dans chaque magasin mais seulement si c'est connecté. – Blackbam

Répondre

3

Je suppose que dans cette situation, vous avez déjà une collection de shop s et une collection de article s, et vous souhaitez simplement lier deux ensemble.

Une option est d'exposer une plus db comme « ressource » qui présente ce lien, et ont des opérations telles que

POST /shopArticleLinks HTTP/1.1 

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

je regarderais personnellement de l'exposer comme une propriété des magasins et/ou des objets un manoir plus naturel, comme

PUT /shop/<ID> HTTP/1.1 

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

J'ai utilisé JSON là-bas, mais bien sûr, utilisez le format que vous voulez utiliser. Je suis également resté avec PUT comme vous l'avez indiqué, mais gardez à l'esprit qu'avec PUT vous devriez envoyer un remplacement complet pour la nouvelle version modifiée, PATCH peut être utilisé pour envoyer des mises à jour partielles, mais alors vous devez considérer comment vous voulez faire que, quelque chose comme peut

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

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

ne pas oublier que côté serveur, vous pouvez regarder ce que articles sont en cours arbitré et veiller à ce qu'ils ont un pointeur arrière approprié.


pensées supplémentaires

En ce qui concerne la deuxième méthode, où vous exposez le lien comme une propriété du shop et/ou article ressources. Gardez à l'esprit qu'il est parfaitement acceptable (et dans ce cas plutôt approprié) que lorsque vous mettez à jour les liens dans un shop donné que les liens dans le articles correspondant sont également mis à jour.

+0

Cela semble viable, mais créer une nouvelle ressource juste pour lier 2 autres est une étape sur la voie de ce que les modèles de conception appellent * "explosion de classe" * –

+0

Ouais, ce n'est certainement pas l'option que j'irais avec. Il reflète la façon dont il serait probablement stocké dans la base de données, mais cela ignore la partie "REpresentation" de REST: P – thecoshman

2

/shop/id/article/id/

Vous ne pouvez pas utiliser car au moment où vous voulez les relier, ce critère d'évaluation n'a pas (ou du moins ne devrait pas) encore exister. C'est l'action de les relier entre eux qui devrait définir ce point final.

/shoparticlerelation/

Vous ne devriez pas utiliser cela parce qu'un shoparticlerelation n'est pas une ressource/entité. Habituellement avec repos, chaque segment d'URL nommé représente une ressource qui peut être CRUD-ed. /shops est un bon exemple et est donc /articles mais celui-ci ne l'est pas.


Je suggère ce qui suit:

Définir les critères d'évaluation suivants

/shops pour POSTer nouveaux magasins
/shops/id pour faire fonctionner sur une seule boutique
/articles pour POSTer nouveaux articles
/articles/id pour exploitation sur un seul article

ensuite de les relier entre eux, vous pouvez faire une soi-disant demande PATCH, de mettre à jour les articles ou les magasins d'un article d'un magasin:

PATCH /shops/1 HTTP/1.1 

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

et

PATCH /articles/9 HTTP/1.1 

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

Sur la base de vos commentaires que je fait l'hypothèse qu'un modèle d'article a une liste de magasins comme attribut, et vice-versa, rendant cette approche valide.

Une requête PATCH est utilisée pour modifier une ressource existante en spécifiant comment et quoi mettre à jour. Ceci est différent d'un PUT car un PUT remplace la ressource entière par des valeurs de la requête, cependant PATCH est seulement utilisé pour modifier (et non remplacer) une ressource.

+0

Je vous donnerais +1 pour suggérer PATCH, mais il est annulé en utilisant deux demandes pour une action. – thecoshman

+0

@thecoshman J'ai suggéré 2 façons de les lier ici avec les 2 demandes de patch. Je les relierais probablement dans les deux sens dans la même requête, quelle que soit la ressource par laquelle vous corrigez. –

+0

Ah je vois, fondamentalement ce que j'ai suggéré, mais pas aussi explicitement. – thecoshman