Il est compréhensible d'être un peu confus sur la façon d'utiliser correctement REST en fonction de toutes les façons dont j'ai vu de grandes entreprises concevoir leurs API REST.
Vous avez raison en ce que REST est un système de collecte de ressources. Cela signifie Représentational State Transfer. Pas une bonne définition si vous me demandez. Mais les principaux concepts sont les 4 VERBES HTTP et être sans état.
La chose importante à noter est que vous n'avez que 4 VERBES avec REST. Ce sont GET, POST, PUT et DELETE. Votre resend
exemple serait d'ajouter un nouveau verbe à REST. Cela devrait être un drapeau rouge.
question 1
Il est important de réaliser que l'appelant de votre API REST ne devrait pas avoir à savoir que l'exécution d'un PUT
sur votre collection entraînerait la génération d'un e-mail. Ça sent une fuite pour moi. Ce qu'ils pouvaient savoir, c'est que l'exécution d'une PUT
tâche pouvait entraîner des tâches supplémentaires qu'ils pourraient interroger plus tard. Ils le sauraient en effectuant une GET
sur la ressource récemment créée. Cela GET
retournerait la ressource et tous les Task
identifiants de ressource qui lui sont associés. Vous pouvez ensuite interroger ces tâches plus tard pour déterminer leur statut et même en soumettre une nouvelle Task
.
Vous avez quelques options.
REST - Approche basée sur les ressources de tâches
Créez une tasks
ressource dans laquelle vous pouvez soumettre des tâches spécifiques dans votre système pour effectuer des actions. Vous pouvez ensuite effectuer GET
la tâche en fonction de la valeur ID
renvoyée pour déterminer son état.
Ou vous pouvez mélanger dans un SOAP over HTTP
service Web afin d'ajouter du RPC à votre architecture.
interroger toutes les tâches pour une ressource spécifique
GET http://server/api/myCollection/123/tasks
{ "tasks" :
[ { "22333" : "http://server/api/tasks/223333" } ]
}
exemple de ressource de tâche
PUT http://server/api/tasks
{
"type" : "send-email" ,
"parameters" :
{
"collection-type" : "foo" ,
"collection-id" : "123"
}
}
==> renvoie l'id de la tâche
223334
GET http://server/api/tasks/223334
{
"status" : "complete" ,
"date" : "whenever"
}
REST - Utilisation de POST pour déclencher des actions
Vous pouvez toujours POST
ajouter des données à une ressource. À mon avis, cela violerait l'esprit de REST, mais ce serait toujours conforme.
Vous pouvez faire un POST similaire à ceci:
POST http://server/api/collection/123
{ "action" : "send-email" }
Vous mettrez à jour la ressource 123 de la collection avec des données supplémentaires. Ces données supplémentaires sont essentiellement une action demandant au backend d'envoyer un e-mail pour cette ressource.
Le problème que j'ai avec ceci est qu'un GET
sur la ressource retournera ces données mises à jour. Cependant, cela résoudrait vos besoins tout en étant RESTful.
SOAP - Service Web qui accepte les ressources obtenues à partir de REST
Créez un nouveau WebService dans lequel vous pouvez envoyer des e-mails en fonction de l'ID de ressource précédent à partir de l'API REST. Je n'entrerai pas dans les détails de SOAP ici car la question d'origine concerne REST et ces deux concepts / technologies ne doivent pas être comparés car ce sont des pommes et des oranges .
question 2
Vous avez également quelques options ici:
Il semble que de nombreuses grandes entreprises qui publient des API REST exposent une search
collection qui n'est vraiment qu'un moyen de transmettre des paramètres de requête pour renvoyer des ressources.
GET http://server/api/search?q="type = myCollection & someField >= someval"
Qui retournerait une collection de ressources REST pleinement qualifiées telles que:
{
"results" :
{ [
"location" : "http://server/api/myCollection/1",
"location" : "http://server/api/myCollection/9",
"location" : "http://server/api/myCollection/56"
]
}
}
Ou vous pouvez autoriser quelque chose comme MVEL comme paramètre de requête.
question 3
Je préfère les sous-niveaux que d'avoir à remonter et interroger l'autre ressource avec un paramètre de requête. Je ne pense pas qu'il existe une règle d'une manière ou d'une autre. Vous pouvez implémenter les deux façons et permettre à l'appelant de décider lequel est le plus approprié en fonction de la façon dont il est entré pour la première fois dans le système.
Remarques
Je ne suis pas d'accord sur les commentaires de lisibilité des autres. Malgré ce que certains pourraient penser, REST n'est toujours pas destiné à la consommation humaine. C'est pour la consommation de la machine. Si je veux voir mes Tweets, j'utilise le site Web régulier de Twitters. Je n'effectue pas de REST GET avec leur API. Si je veux faire quelque chose par programme avec mes tweets, j'utilise leur API REST. Oui, les API doivent être compréhensibles, mais ce gte
n'est pas si mal, ce n'est tout simplement pas intuitif.
L'autre chose principale avec REST est que vous devriez pouvoir commencer à tout moment donné dans votre API et naviguer vers toutes les autres ressources associées SANS connaître à l'avance l'URL exacte des autres ressources. Les résultats du GET
VERBE dans REST doivent renvoyer l'URL REST complète des ressources qu'il référence. Ainsi, au lieu d'une requête renvoyant l'ID d'un Person
objet, il retournerait l'URL entièrement qualifiée telle que http://server/api/people/13
. Ensuite, vous pouvez toujours parcourir par programme les résultats même si l'URL a changé.
Réponse au commentaire
Dans le monde réel, il y a en fait des choses qui doivent se produire qui ne créent, lisent, mettent à jour ou suppriment (CRUD) une ressource.
Des actions supplémentaires peuvent être prises sur les ressources. Les bases de données relationnelles typiques prennent en charge le concept de procédures stockées. Ce sont des commandes supplémentaires qui peuvent être exécutées sur un ensemble de données. REST n'a pas intrinsèquement ce concept. Et il n'y a aucune raison que ce soit le cas. Ces types d'actions sont parfaits pour les services Web RPC ou SOAP.
C'est le problème général que je vois avec les API REST. Les développeurs n'aiment pas les limitations conceptuelles qui entourent REST, ils l'adaptent donc pour faire ce qu'ils veulent. Cela le rompt cependant d'être un service RESTful. Essentiellement, ces URL deviennent des GET
appels sur des servlets de type pseudo-REST.
Vous avez quelques options:
- Créer une ressource de tâche
- Prise
POST
en charge de données supplémentaires sur la ressource pour effectuer une action.
- Ajoutez les commandes supplémentaires via un service Web SOAP.
Si vous avez utilisé un paramètre de requête quel VERBE HTTP utiliseriez-vous pour renvoyer l'e-mail?
GET
- Est-ce que cela renvoie l'e-mail ET renvoie les données de la ressource? Et si un système mettait cette URL en cache et la traitait comme l'URL unique de cette ressource. Chaque fois qu'ils frappaient l'URL, il renvoyait un e-mail.
POST
- Vous n'avez pas réellement envoyé de nouvelles données à la ressource, juste un paramètre de requête supplémentaire.
Sur la base de toutes les exigences données, faire un POST
sur la ressource avec des action field
données POST résoudra le problème.