111 votes

Comment modéliser une API RESTful avec héritage?

J'ai une hiérarchie d'objets j'ai besoin de dénoncer à travers une API RESTful et je ne suis pas sûr de savoir comment mon Url doit être structurée et ce qu'ils doivent revenir. Je ne pouvais pas trouver toutes les meilleures pratiques.

Disons que j'ai des Chiens et des Chats héritant de Animaux. J'ai besoin d'opérations CRUD sur les chiens et les chats; je veux aussi être capable de faire des opérations sur les animaux en général.

Ma première idée était de faire quelque chose comme ceci:

GET /animals        # get all animals
POST /animals       # create a dog or cat
GET /animals/123    # get animal 123

Le truc, c'est que la /les animaux de la collection est maintenant "incohérent", comme on peut le retourner et prendre des objets qui n'ont pas exactement la même structure (chiens et chats). Est-ce considéré comme de "repos" pour avoir une collection de retourner les objets ont des attributs différents?

Une autre solution serait de créer une URL pour chaque type de béton, comme ceci:

GET /dogs       # get all dogs
POST /dogs      # create a dog
GET /dogs/123   # get dog 123

GET /cats       # get all cats
POST /cats      # create a cat
GET /cats/123   # get cat 123

Mais maintenant, la relation entre les chiens et les chats est perdu. Si l'on souhaite récupérer tous les animaux, le chien et le chat les ressources doivent être interrogés. Le nombre d'Url va également augmenter avec chaque nouvel animal de sous-type.

Une autre suggestion consistait à accroître la deuxième solution en ajoutant ceci:

GET /animals    # get common attributes of all animals

Dans ce cas, les animaux de renvoyer uniquement contenir des attributs communs à tous les animaux, à l'abandon de chien spécifique et chat-des attributs particuliers. Cela permet de récupérer tous les animaux, bien qu'avec moins de détails. Chaque objet retourné pourrait contenir un lien vers les détails, version concrète.

Des commentaires ou des suggestions?

46voto

Brian Kelly Points 9433

Je vous suggère:

  • En utilisant un seul URI par ressource
  • La différenciation entre les animaux uniquement au niveau des attributs

L'installation de plusieurs Uri pour la même ressource n'est jamais une bonne idée, car il peut causer de la confusion et des effets secondaires inattendus. Étant donné que, votre seul URI doit être basée sur un schéma générique comme /animals.

Le prochain défi de traiter avec l'ensemble de la collection de chiens et de chats à la "base" de niveau est déjà résolu, en vertu de l' /animals URI approche.

Le dernier défi de traiter avec des types spécialisés comme les chiens et les chats peuvent être facilement résolu en utilisant une combinaison de paramètres de la requête et de l'identification des attributs au sein de votre type de média. Par exemple:

GET /animals (Accept : application/vnd.vet-services.animals+json)

{
   "animals":[
      {
         "link":"/animals/3424",
         "type":"dog",
         "name":"Rex"
      },
      {
         "link":"/animals/7829",
         "type":"cat",
         "name":"Mittens"
      }
   ]
}
  • GET /animals - obtient tous les chiens et les chats, serait de retour à la fois Rex et des Mitaines
  • GET /animals?type=dog - obtient tous les chiens, ne renvoie Rex
  • GET /animals?type=cat - obtient tous les chats, ne Mitaines

Ensuite, lors de la création ou de la modification d'animaux, il incombe à l'appelant de spécifier le type d'animaux impliqués:

Type De Média: application/vnd.vet-services.animal+json

{
   "type":"dog",
   "name":"Fido"
}

La charge ci-dessus pourrait être envoyé avec un POST ou PUT de la demande.

Le schéma ci-dessus vous permet de vous la base des caractéristiques similaires OO héritage par le REPOS, et avec la possibilité d'ajouter d'autres spécialisations (c'est à dire plus de types d'animaux) sans intervention chirurgicale majeure ou de toute modification à votre schéma d'URI.

4voto

Jørn Wildt Points 828

Je voudrais aller /animaux retour d'une liste de deux chiens et des poissons et quoi d'autre:

<animals>
  <animal type="dog">
    <name>Fido</name>
    <fur-color>White</fur-color>
  </animal>
  <animal type="fish">
    <name>Wanda</name>
    <water-type>Salt</water-type>
  </animal>
</animals>

Il devrait être facile à mettre en œuvre une semblable JSON exemple.

Les Clients peuvent toujours compter sur l'élément "name" être là (un attribut commun). Mais en fonction de l'attribut "type", il y aura d'autres éléments dans le cadre de la représentation animale.

Il n'y a rien d'intrinsèquement Reposante ou parsèments dans le retour d'une telle liste REPOS ne prescrit pas de format spécifique pour représenter des données. Tout ce qu'elle dit est que les données doivent avoir certains de représentation et le format pour que cette représentation est identifié par le type de média (qui dans HTTP est le header Content-Type).

Pensez à votre cas d'utilisation - avez-vous besoin d'afficher une liste d'mixte des animaux? Bien, alors retourne une liste des mixtes de données sur les animaux. Avez-vous besoin d'une liste de chiens, seulement? Ainsi, faire une telle liste.

Si vous n' /animaux?type=chien ou les chiens /est sans pertinence à l'égard de REPOS qui ne prescrit pas de formats URL - c'est-à gauche comme un détail d'implémentation en dehors de la portée de REPOS. REPOS indique seulement que les ressources devraient avoir des identifiants - jamais l'esprit de ce format.

Vous devez ajouter un peu hyper media en les reliant à se rapprocher d'une API RESTful. Par exemple en ajoutant des références à l'animal de détails:

<animals>
  <animal type="dog" href="http://stackoverflow.com/animals/123">
    <name>Fido</name>
    <fur-color>White</fur-color>
  </animal>
  <animal type="fish" href="http://stackoverflow.com/animals/321">
    <name>Wanda</name>
    <water-type>Salt</water-type>
  </animal>
</animals>

En ajoutant hyper media liens vous réduire client/serveur de couplage dans le cas ci-dessus, vous prenez la charge de la construction d'une URL loin du client et de laisser le serveur de décider de la façon de construire l'Url (qui par définition est la seule autorité).

1voto

Grzesiek D. Points 656

Mais maintenant, la relation entre les chiens et les chats est perdue.

En effet, mais gardez à l’esprit que l’URI ne reflète jamais les relations entre les objets.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X