2012-06-29 3 views
2

Est-ce une bonne structure pour les URL REST?REST Emplacement de l'ID d'URL pour les ressources avec collections

En supposant:

GET /account <- get list of accounts 
GET /account/1234 <- get account 1234 

etc.

Si la ressource de compte a une collection que je veux à l'interface, est-ce une bonne idée?

GET /account/1234/note <- get notes for account 1234 
POST /account/1234/note <- add note to account 1234 
DELETE /account/1234/note/321 <- delete note 321 on account 1234 

Surtout que le dernier me donne une pause; En général, je n'aurais pas besoin à la fois de l'identifiant de l'entité et de l'identifiant parent lors de la suppression.

Ou peut-être que quelque chose comme ça serait mieux?

GET /account-note/1234 <- get notes for account 1234 
POST /account-note/1234 <- add note to account 1234 
DELETE /account-note/321 <- delete note 321 on account 1234 (b/c note 321 is on account 1234) 

Mais alors je me retrouverais avec un jeu d'URL assez peu profond.

Merci

Répondre

0

J'ai fait référence à cette question dans mes commentaires sur une autre question et entre les commentaires que j'ai reçus et mes propres recherches, c'est ce que j'ai trouvé.

Tout d'abord, la question est en quelque sorte erronée. APIs RESTful, ou pour utiliser le terme Perferable API Hypermedia devrait inclure les URL des actions connexes de sorte que l'interface est découvrable et les changements ne cassera pas les clients existants, donc la structure exacte a significativement moins d'importance que je plaçais sur elle, ceux-ci peuvent être changé plus tard.

En second lieu, la note dans l'exemple sera récupéré dans le cadre d'une requête de compte, peut-être quelque chose comme ceci:

<account> 
    ... 
    <notes> 
     <note> 
     ... 
     <link href="/account-note/123" rel="note"> 
     </note> 
    </notes> 
</account> 

Le client ne sera jamais assemblera urls au compte de leur propre chef, le client utilisez le lien fourni. Puisque l'ID de note est globalement unique dans ce cas, il n'est pas nécessaire d'inclure la clé deux fois. D'où la réponse à la question est non, le premier exemple n'est pas une bonne structure d'URL REST, le second est meilleur. (Bien que peut-être pas encore le meilleur ...)

+0

Désolé je ne suis pas d'accord. Outre les bons points soulevés par @Ben, votre deuxième moyen force le client à analyser la sortie d'une requête de compte avant que le client puisse accéder aux notes. D'où le double de la latence. – RayLuo

+0

C'est un principe de HATEOAS, que la réponse d'une opération RESTful renvoie les URL des opérations supportées sur la ressource. Il existe de nombreuses façons de fournir les URL, soit en utilisant un protocole propriétaire (qui n'est pas si utile à mon humble avis) ou un format défini comme Hypermtext Application Language (HAL). Il n'y a vraiment aucune raison de s'inquiéter de l'analyse du client - le travail effectué sur le client va bien sûr à l'échelle 1: 1 lorsque les clients sont ajoutés, et lire une URL ne demande pas beaucoup de travail et la bande passante supplémentaire est un petit prix à payer avantages [suite] – Paul

+0

Il est difficile de faire cela de la bonne manière, car peu (aucun?) des frameworks supportent quelque chose comme HAL. Aussi REST est juste un outil, c'est juste une façon de faire les choses, si vous avez un cas où REST comporte de faibles avantages (un exemple qui saute aux yeux serait un scénario où vous possédez à la fois client et serveur, le ratio de les clients vers les serveurs sont faibles, et le débit est très important - et peut-être que vous utilisez des services cellulaires ou quelque chose de coûteux) vous êtes totalement libre d'implémenter n'importe quel type de protocole, sans respecter aucun principe RESTful. – Paul

-1

Rappelez-vous, mon expérience est avec JAX-RS et Jersey, donc je ne suis pas sûr de ce que les différences exactes.

Cependant, c'est ce que je ferais:

@GET 
    @Path ("/account/note/{id}") 
    public void displayNotes(@PathParam ("accountId") String accountId) 
    { 
     //do stuff 
    } 

    @POST 
    @Path ("/account/note") 
    public void addNote(@FormParam ("accountId") String accountId) 
    { 
     //do stuff 
    } 

    @POST 
    @Path ("/account/note/delete") 
    public void deleteNote(@FormParam ("accountId") String accountId, @FormParam ("noteId") String noteId) 
    { 
     //do stuff 
    } 

De cette façon, vous n'avez pas les URL encombrés et confus que l'utilisateur n'a pas besoin de voir de toute façon, surtout si l'utilisateur tente de naviguer là par leurs propres moyens. Ce qui est correct pour afficher les comptes, mais les confondrait avec les URLs POST, puisqu'ils obtiendraient un 404 et ne comprendraient pas pourquoi. Restez simple, et utilisez simplement @FormParams car l'utilisateur n'a pas besoin de le voir de toute façon.

+0

Euh, cet exemple n'est pas vraiment repos ... – Paul

+0

Totalement pas RESTful. Vous devriez supprimer des choses avec le verbe 'DELETE', c'est le moins qu'on puisse dire. –

2

Il n'y a rien de mal avec votre première API. En grande partie, l'idée de l'interface RESTful est d'aller avec la structure naturelle de l'arbre du web, et votre première approche est en accord avec cela. Il s'agira également d'une structure qui fait abstraction des contraintes implicites de votre banque de données par l'API, car la deuxième approche suppose implicitement que l'ID de note est globalement unique. Cela peut être vrai maintenant, et restera probablement vrai, mais c'est aussi exactement le genre de bug qui apparaît soudainement avec des conséquences désastreuses quand, en bas de la ligne, une sorte de changement majeur se produit.

J'irais avec votre premier schéma. C'est un schéma de repos familier, intuitif et qui ne va pas exploser de façon étrange. En outre, en réponse à @ Corwin01, minimisez les paramètres de requête - ils ne sont pas si RESTful.

Questions connexes