web-dev-qa-db-fra.com

Quel est le meilleur modèle pour ajouter un élément existant à une collection dans REST API?

Je conçois une API REST API 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 a une collection de sites. C'est une relation plusieurs-à-plusieurs stricte 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?

25
Jamie Ide

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 et siteId 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? Devriez-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,

les seules données dont j'ai vraiment besoin sont ProjectId et SiteId

Au lieu de cela, j'essayerais de POSER le siteId à la collection, et je compterais sur la nature "append" et "process" de POST:

POST myapi/projets/{projectId}/sites

{'id': '...'}

Puisque vous modifiez les sites ressource de collection et non le site ressource, 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 collecte obtient un identifiant et rien d'autre, il est assez clair ce qui doit se produire.

Question interessante. :)

15
Rob

Nous utilisons la méthode Patch 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

PATCH myapi/projects/{id} 

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.

4
juan