Qu'est-ce que le repos de façon à représenter une ressource opération de duplication dans l'URL?
J'ai API REST qui expose un grand complexe de ressources et je veux être en mesure de cloner cette ressource. Supposons que la ressource est exposée à /resources/{resoureId}
De cloner des ressources 10 je pouvais faire quelque chose comme.
GET /resources/10
POST /resources/
corps de contenant une copie de la représentation parGET /resources/10
sans l'id de sorte que lePOST
crée une nouvelle ressource.
Le problème avec cette approche est que la ressource est très vaste et complexe qu'elle ne fait pas vraiment de sens pour retourner une représentation complète au client et que le client renvoyer comme ça serait juste une perte totale de la bande passante, et de la cpu sur le serveur. Le clonage de la ressource sur le serveur est tellement plus facile si je veux le faire.
Je pourrais faire quelque chose comme POST /resources/10/clone
ou POST resources/clone/10
mais ces deux approches se sentir mal parce que le verbe dans l'URL.
Ce qui est le plus "reposante/nouny" moyen de construire l'url qui peut être utilisé dans ce type de situation?
- Honnêtement, je pense que c'est parfaitement ok pour juste ajouter /clone à la fin de l'url parce que "clone" est aussi un nom, et dans ce cas, la chose que vous êtes en train de créer.
Vous devez vous connecter pour publier un commentaire.
Puisqu'il n'est pas de copier ou de méthode clone en HTTP, c'est à vous de décider ce que vous voulez faire. Dans ce cas, un
POST
semble parfaitement raisonnable, mais d'autres normes ont adopté des approches différentes:COPIER
méthode.PUT
sans corps et un spécialx-amz-copy-source
en-tête. Ils appellent cela uneMETTRE l'Objet de Copie
.Deux de ces approches supposent que vous savez l'URI de destination. Votre exemple me semble pas une destination connue d'uri, de sorte que vous avez à peu près doit utilisation POST. Vous ne pouvez pas utiliser les METTRE ou COPIE parce que votre opération de création n'est pas idempotent.
Si votre service définit
POST /resources
comme "créer une nouvelle ressource", alors pourquoi ne pas simplement définir une autre façon de spécifier la ressource autre que le corps de la POSTE? E. g.POST /resources?source=/resources/10
dont le corps est vide.sourceId
dans le corps et je ne l'aime pas.POST /resources?source=/resources/10
, quelle est la "bonne" façon d'obtenir/resources/10
à l'intérieur de mon API? L'idée est d'appeler l'OBTENIR pour/resources/10
à l'intérieur de mon API ou est seulement un moyen d'obtenir la carte d'identité?POST /resources?sourceId=10
au lieuPOST /resources?copyOf=10
La réponse de françois est un grand et probablement ce que vous cherchez. Cela étant dit, il n'est pas techniquement Reposante depuis (comme il le dit dans les commentaires) il repose sur le client de la prestation de la bande d'information. Puisque la question était "qu'est-ce que le repos" et pas "qu'est ce qu'un bon moyen de/la meilleure façon", qui m'a fait penser qu'il y est une bonne solution. Et je pense que ce qui suit est une bonne solution, même si je ne suis pas sûr que c'est forcément mieux dans la pratique.
Tout d'abord, comme vous l'avez déjà identifié, OBTENIR suivie par la POSTE est la simple et évidente Reposant façon, mais il n'est pas efficace. Nous sommes donc à la recherche d'une optimisation, et nous ne devrions pas être trop surpris si il se sent un peu moins naturel que celui que la solution!
Le POST + sourceId solution crée une URL spéciale - celle qui ne pas une ressource, mais à une instruction de faire quelque chose. Toutes les fois que vous vous trouvez créer une Url comme ça, il est utile d'envisager si vous pouvez travailler autour de la nécessité de le faire en définissant simplement plus de ressources.
Nous voulons que la possibilité de copier
Que si nous trouvons une autre ressource:
...et la définition de cette ressource est tout simplement "la collection de ressources qui sont des copies de ressources/10".
Avec cette ressource définie, nous pouvons maintenant re-état de notre opération de copie en des termes différents - au lieu de dire "je veux que le serveur afin de copier les ressources/10", on peut dire "je veux ajouter une chose nouvelle à la collection de choses qui sont des copies de ressources/10".
Cela semble étrange, mais il s'inscrit naturellement dans le REPOS de la sémantique. Par exemple, disons que cette ressource actuellement ressemble à ça (je vais utiliser une représentation JSON ici):
On peut juste mettre à jour qu'avec un POST ou d'un PATCH [1]:
Noter que tous que nous allons envoyer au serveur de métadonnées à propos d'une collection, de sorte qu'il est très efficace. On peut supposer que le serveur sait maintenant où trouver les données à copier, car cela fait partie de la définition de cette ressource. On peut aussi supposer que le client sait qu'il en résulte une nouvelle ressource a été créé à "ressources/11" pour la même raison.
Avec cette solution, tout est clairement définie comme une ressource, et de tout ce qui a une URL canonique, et pas de bande d'information est requis par le client.
En fin de compte, est-il la peine d'aller avec cet étrange sentiment solution juste pour le plaisir d'être plus Reposant? Que, probablement, dépend de votre projet. Mais il est toujours intéressant d'essayer et de structurer le problème différemment par la création de différentes ressources!
[1] je ne sais pas si a de sens pour permettre d'OBTENIR sur le thème "ressources/10/copie". Évidemment, dès que la ressource d'origine ou d'une copie de ce changement, la copie n'est pas vraiment une copie plus et ne devrait pas être dans cette collection. Mise en œuvre-sage, je ne vois pas l'intérêt de surcharger le serveur avec le maintien de la piste, donc je pense que cela devrait être traitée comme une mise à jour seule ressource.
POST resources/10/copies/
au lieu dePOST resources/copies/10
?Je pense que
POST /resources/{id}
serait une bonne solution pour copier une ressource.Pourquoi?
POST /resources
est la valeur par défaut RESTE-Standard pour CRÉER une nouvelle ressourcePOST /resources/{id}
ne devrait pas être possible dans la plupart des api REST, parce que l'id existe déjà - vous ne sera jamais de générer une nouvelle ressource avec vous (le client) de la définition de l'identité. Le serveur va définir l'id.Notez également que vous ne serez jamais copier la ressource Une ressource B. Donc, si vous voulez copier les ressources existantes avec l'id=10, quelques réponses de proposer ce genre de chose:
mais c'est plus simple:
qui crée une copie de 10 - vous devez récupérer 10 de stockage, donc si vous ne le trouvez pas, vous ne pouvez pas copier = jeter un 404 not Found.
Si elle n'existe pas, vous créez une copie de celui-ci.
Donc, en utilisant cette idée, vous pouvez le voir, il ne fait pas de sens de le faire, la copie de certains b de ressources pour certains, une ressource:
Alors, pourquoi ne pas simplement utiliser le POST /ressources/{id}
{id}
Que pensez-vous de cela?
Vous voulez créer une copie d'une ressource spécifique. Mon Approche dans ce cas, serait d'utiliser le endpoint suivant :
POST /resources/{id}/copy
, lire "créer une copie de la ressource {id}"Va juste mettre ça là, si cela peut aider quelqu'un.
Nous avons eu un scénario similaire, où nous avons été la fourniture de "vm" comme une fonction de mise à l'échelle sur notre offre IaaS. Donc, si un utilisateur veut évoluer, ils auraient frappé
POST: /vms/vm101
point de terminaison avec request_body êtreet 3 clones de vm101 viz. vm102, vm103 et vm104 serait spinned.