web-dev-qa-db-fra.com

Comment concevoir une API REST pour gérer les opérations non-CRUD?

J'essaie de convertir un ensemble de services basés sur SOAP en une API RESTful.

J'ai commencé par identifier les ressources en analysant les noms des opérations et j'ai obtenu la ressource Subscription.

Lorsque j'ai besoin de mettre à jour l'état de l'abonnement, je ne peux pas simplement envoyer une demande POST au serveur, car je n'ai pas d'accès direct aux ressources, mais je dois appeler des opérations de style RPC à mettre à jour leurs propriétés. De plus, uniquement et uniquement si je modifie l'état de l'abonnement sur "actif", un appel supplémentaire vers un service externe est requis.

Dans ces cas, quelle est la meilleure pratique pour gérer les opérations sous-jacentes?

La solution que j'ai trouvée est d'utiliser des paramètres de requête, de sorte que si j'ai besoin d'appeler le service d'activation, je peux utiliser quelque chose comme:

POST /subscriptions/{subscriptionid}/?activate=true

Étant donné que je ne peux pas mettre à jour directement mes champs d'objet d'abonnement, existe-t-il une meilleure pratique pour gérer ce type de conversion?

Mise à jour 1:

Je peux mettre dans le corps de ma POST demande quelques valeurs, par exemple "state": "active"

et vérifier à l'intérieur de mon service les opérations à déclencher.

11
Vektor88

Vous devez regarder cet exposé par Jim Webber.

Lorsque je dois mettre à jour l'état de l'abonnement, je ne peux pas simplement envoyer une demande POST au serveur, car je n'ai pas d'accès direct aux ressources, mais je dois appeler un RPC -style operations pour mettre à jour leurs propriétés. De plus, seulement et seulement si je change l'état de l'abonnement en "actif", un appel supplémentaire à un service externe est requis.

Pensez "messagerie"; envoyer un message à votre domaine, décrivant ce que vous voulez que cela se produise. L'effet secondaire du message est que votre modèle de domaine change réellement son état. La "ressource" est la file d'attente de messages.

POST /subscriptions/{subscriptionid}/?activate=true

L'orthographe du nom de la ressource n'a pas d'importance pour les machines; mais les gens ont tendance à être pointilleux lorsque les identifiants que vous utilisez ne respectent pas la convention selon laquelle les ressources sont des "noms".

En outre, nous parlons d'une ressource qui est subordonnée à /subscriptions/{subscriptionid}, donc la convention (voir RFC 3986 ) demande d'exprimer cette relation avec un segment de chemin, plutôt que d'utiliser la partie requête.

Donc, ces orthographes pourraient être raisonnables

POST /subscriptions/{subscriptionid}/messages
POST /subscriptions/{subscriptionid}/activations
8
VoiceOfUnreason

Si c'est un drapeau booléen pour activer/désactiver des trucs, je dirais que la valeur par défaut est d'utiliser JSON:

POST /subscriptions/{subscriptionid}/
{
    format: 0,
    subscription: 
    {
        active: false
    }
}

Ceci est facilement étendu si vous souhaitez prendre en charge plus de propriétés. Une autre approche lui donne son propre point final:

POST /subscriptions/{subscriptionid}/active/
DELETE /subscriptions/{subscriptionid}/active/

Personnellement, je n'utiliserais cela que si l'état active de cet événement a besoin/possède des propriétés que vous pouvez ensuite passer/obtenir en JSON, comme un ID utilisateur ou un paramètre.

Si ce n'est pas une valeur booléenne mais juste une action que vous devez déclencher mais dont vous n'avez pas besoin/n'avez aucun retour d'état (à l'exception d'un 200 OK immédiat), j'utiliserais un point de terminaison comme celui-ci pour le déclencher un peu comme un RPC:

POST /subscriptions/{subscriptionid}/activate/

En cas de doute, lisez ceci: http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api#restful (voir "Qu'en est-il des actions qui ne correspondent pas dans le monde des opérations CRUD? ")

0
Barry Staes

REST n'est pas fonctionnel. Activate est un verbe et ne peut pas être un état, Active est un état.

Étant donné que RESTful n'est pas fonctionnel, vous ne pouvez pas dire à un service RESTful quoi faire, mais vous pouvez ajouter du travail pour la file d'attente d'un service.

Regarde ça:

PUT /subscriptionQueue
subscriptionId={subscriptionId}
active=true

Cette demande est RESTful et prend en charge tous les avantages de RESTful (comme les performances, l'acide ...)

0
Peter Rader