Je conçois une API REST pragmatique et je suis un peu coincé sur la meilleure façon d'ajouter des entités existantes à une collection. Mon modèle de domaine comprend un projet qui possède une collection de sites. Il s'agit d'une stricte relation plusieurs-à-plusieurs et je n'ai pas besoin de créer une entité qui modélise explicitement la relation (c'est-à-dire ProjectSite).
Mon API permettra aux consommateurs d'ajouter un site existant à un projet. Là où je me bloque, c'est que les seules données dont j'ai vraiment besoin sont ProjectId et SiteId. Mon idée initiale était:
1. POST myapi/projects/{projectId}/sites/{siteId}
Mais j'ai aussi pensé à
2. POST myapi/projects/{projectId}/sites
avec une entité Site envoyée en tant que contenu JSON.
L'option 1 est simple et fonctionne mais ne semble pas tout à fait correcte, et j'ai d'autres relations qui ne peuvent pas suivre ce modèle, ce qui ajoute une incohérence à mon API.
L'option 2 se sent mieux mais conduit à deux préoccupations:
- Dois-je créer un site ou lever une exception si un nouveau site est publié (SiteId = 0)?
- Étant donné que je n'ai besoin que de ProjectId et SiteId pour créer la relation, le site peut être publié avec des données incorrectes ou manquantes pour d'autres propriétés.
Une troisième option consiste à fournir un point de terminaison simple uniquement pour créer et supprimer la relation. Ce point de terminaison attendrait une charge utile JSON contenant uniquement ProjectId et SiteId.
Qu'est-ce que tu penses?
la source
Réponses:
POST est le verbe "append", ainsi que le verbe "processing". PUT est le verbe "créer / mettre à jour" (pour les identificateurs connus), et ressemble presque au bon choix ici, car l'URI cible complet est connu.
projectId
etsiteId
existent déjà, vous n'avez donc pas besoin de "POST vers une collection" pour produire un nouvel ID.Le problème avec PUT est qu'il requiert que le corps soit la représentation de la ressource que vous PUTtez. Mais l'intention ici est d'ajouter à la ressource de collection "projet / sites", plutôt que de mettre à jour la ressource Site.
Et si quelqu'un met une représentation JSON complète d'un site existant? Devez-vous mettre à jour la collection et mettre à jour l'objet? Vous pourriez soutenir cela, mais il semble que ce ne soit pas l'intention. Comme tu dis,
Au lieu de cela, j'essayerais de POSTER le
siteId
dans la collection, et je compterais sur la nature "ajouter" et "traiter" de POST:Puisque vous modifiez la ressource de collection de sites et non la ressource de site , c'est l'URI que vous souhaitez. POST peut savoir «ajouter / traiter» et ajouter l'élément avec cet identifiant à la collection de sites du projet.
Cela laisse toujours la porte ouverte à la création de nouveaux sites pour le projet en étoffant le JSON et en omettant l'identifiant. "No id" == "créer à partir de zéro". Mais si l'URI de collection obtient un identifiant et rien d'autre, il est assez clair ce qui doit se produire.
Question interessante. :)
la source
POST
placePUT
ouPATCH
ici est que vous n'avez pas l'Site
entité entière à mettre dans lasites
ressource. Vous n'avez que l'ID, ce qui nécessite un traitement pour l'ajouter à la collection.Nous utilisons la
Patch
méthode pour des trucs comme ça. Ce que vous voulez faire, c'est modifier un projet existant pour y ajouter un site.Donc, quelque chose comme ça fonctionnerait
avec l'entité Site (s) en tant que JSON / JSONArray dans le corps de la demande.
De cette façon, vous pouvez utiliser la même URL pour modifier différentes parties du projet si vous en avez besoin - votre code dans l'implémentation doit être suffisamment intelligent pour gérer cette modification partielle de la ressource.
la source
{"sites": [], "other-stuff": {}}
, vous pouvez ensuite brancher votre code pour gérer tous ces "subjsons" très facilement. Cela dépend vraiment de votre problème spécifique, mais je recommanderais toujours d'utiliser PATCH car il est conçu spécifiquement pour ce genre de choses.PATCH
attendriez -vous pas également à ce que l'entité complète soit transmise comme sa valeur ici, plutôt que comme un identifiant qui pointe vers une entité?