2009-07-25 8 views
4

Je construis un petit outil pour aider les gens à décider des activités de groupe, comme le restaurant où ils devraient aller déjeuner. Mes objets sont des événements, des options et des préférences. Un événement a plusieurs options, un utilisateur peut classer les options sur un inventeur dans l'ordre. Ainsi, les votes d'un utilisateur peuvent être 1: option B, 2: option A, 3: option C.Comment est-ce que cela correspond à une interface RESTful?

Ma question est quelle est la meilleure façon de mapper cela à REST? Il semble clair que j'appuyer CRUD sur les événements, avec

GET /events/ : list of events 
POST /events/ : create a new event 
GET /events/1 : get event one 
and on options with: 
POST /events/1/options : add a new option to the event 

(dans tous les cas, il doit y avoir un utilisateur authentifié)

Là où je confonds est de savoir comment un vote utilisateur sur les options pour la un événement. Ce qui semble le mieux correspondre à REST est de faire un PUT pour chaque option, à/events/1/options/1/vote, mais cela semble être difficile à faire respecter les exigences entre les votes, par exemple, si je voulais forcer les votes pour classer les options sans les liens, je pourrais le faire si j'ai obtenu tous les votes à la fois, comme dans 1 B, 2 A, 3 C, mais si l'utilisateur change ses votes à 1 C, 2 B, 3 A, l'application serait dans un état non valide entre ces demandes.

Est-ce que je devrais faire les votes un seul paquet, et y accéder à/events/1/votes?

(Cela peut sembler une quantité excessive de la planification d'un projet de week-end, mais mon but est de le faire droit, puisque je ne l'ai pas le luxe sur le code que je suis payé pour écrire.)

Répondre

4

Depuis votes sont des documents qui se rapportent à un utilisateur, un vote, et une option, je concevoir le vote comme POST-/votes, essentiellement en créer une action pour ces dossiers de vote. Ensuite, vous pouvez combiner évidemment plusieurs votes dans une requête qui ressemble à l'exemple suivant (en JSON):

POST /votes 
[ 
    { option: 38, vote: 2 }, 
    { option: 39, vote: 1 }, 
    { option: 40, vote: 0 } 
]

Sur le serveur vous remplissez l'utilisateur et retourner un code d'état approprié après vos contrôles de cohérence.

0

I ferait de cette façon:

/events/1/options/vote/1stchoice 
/events/1/options/vote/2ndchoice 
/events/1/options/vote/3rdchoice 
/events/1/options/vote/4thchoice 
… 

de cette façon, si l'utilisateur veut voter pour A comme son premier choix, B comme son deuxième choix, etc., il placerait « A »/événements/1/options/vote/1stchoice, "B" vers/events/1/options/vote/2ndchoice, etc.

Si l'utilisateur voulait changer ses choix (s ay, fais B d'abord, un second), il faudrait SUPPRIMER ses votes et ensuite les refondre.

Dans les sondages où les utilisateurs ne peuvent sélectionner qu'une option, seul options/vote/1stchoice est activé.

+0

Les URI n'ont pas d'importance - l'important est que ces URI soient envoyées en réponse à un point d'entrée, en tant que champs, afin que le client n'ait pas à les construire ou à connaître leur contenu. – aehlke

1

Je pense que la première chose que vous devez faire est de déterminer quels sont les objets que vous représentez dans votre interface. C'est le vrai premier principe de la conception d'une interface de repos. Il n'est pas clair si vos objets sont les options/event/où les événements possèdent un ensemble d'options et l'opération est 'ajouter des votes' ou le modèle est/person/preferences/option où les préférences de la personne sont un ensemble options et l'opération est la même 'ajouter des votes'. Dans les deux cas, l'idée précédemment suggérée de POSTER un ensemble d'options en même temps est une approche RESTFUL correcte, où les préférences/person/ou l'événement/sont à la fois propres collections d'options et lorsqu'il s'agit d'une collection, POST est approprié.

Si vous aviez des utilisateurs votant sur des options individuelles, dans les deux cas, vous définiriez le nombre de votes pour une option particulière. Dans ce cas, un PUT sur/event/option/1 ou/person/preference/1 (pour l'option 1) serait approprié

Questions connexes