Cette API REST est-elle vraiment RPC? Roy Fielding semble le penser


99

Une grande partie de ce que je pensais savoir sur REST est apparemment faux - et je ne suis pas seul. Cette question a une longue introduction, mais elle semble nécessaire car les informations sont un peu dispersées. La vraie question vient à la fin si vous êtes déjà familier avec ce sujet.

Depuis le premier paragraphe des API REST de Roy Fielding doivent être basées sur l'hypertexte , il est assez clair qu'il pense que son travail est largement mal interprété:

Je suis frustré par le nombre de personnes qui appellent une interface HTTP une API REST. L'exemple d'aujourd'hui est l' API REST SocialSite . C'est RPC. Il crie RPC. Il y a tellement de couplage à l'écran qu'il devrait recevoir une note X.

Fielding poursuit en répertoriant plusieurs attributs d'une API REST. Certains d'entre eux semblent aller à l'encontre à la fois de la pratique courante et des conseils communs sur les SO et d'autres forums. Par exemple:

  • Une API REST doit être saisie sans aucune connaissance préalable au-delà de l'URI initial (signet) et de l'ensemble de types de supports standardisés qui sont appropriés pour le public visé (c'est-à-dire, censés être compris par tout client qui pourrait utiliser l'API). ...

  • Une API REST ne doit pas définir de noms ou de hiérarchies de ressources fixes (un couplage évident du client et du serveur). ...

  • Une API REST doit consacrer presque tout son effort de description à la définition du ou des types de médias utilisés pour représenter les ressources et à la gestion de l'état de l'application, ou à la définition de noms de relations étendus et / ou de balisage hypertexte pour les types de médias standard existants. ...

L'idée d '"hypertexte" joue un rôle central - bien plus que la structure URI ou ce que signifient les verbes HTTP. "Hypertexte" est défini dans l'un des commentaires:

Quand je [Fielding] dis hypertexte, je veux dire la présentation simultanée d'informations et de contrôles de sorte que l'information devienne le moyen par lequel l'utilisateur (ou l'automate) obtient des choix et sélectionne des actions. Hypermedia est juste une extension de ce que signifie le texte pour inclure des ancres temporelles dans un flux multimédia; la plupart des chercheurs ont abandonné la distinction.

L'hypertexte n'a pas besoin d'être HTML sur un navigateur. Les ordinateurs peuvent suivre les liens lorsqu'ils comprennent le format des données et les types de relations.

J'imagine à ce stade, mais les deux premiers points ci-dessus semblent suggérer que la documentation API pour une ressource Foo qui ressemble à ce qui suit conduit à un couplage étroit entre le client et le serveur et n'a pas sa place dans un système RESTful.

GET   /foos/{id}  # read a Foo
POST  /foos/{id}  # create a Foo
PUT   /foos/{id}  # update a Foo

Au lieu de cela, un agent devrait être forcé de découvrir les URI pour tous les Foos, par exemple en émettant une requête GET contre / foos. (Ces URI peuvent s'avérer suivre le modèle ci-dessus, mais ce n'est pas la question.) La réponse utilise un type de média capable de transmettre comment accéder à chaque élément et ce qui peut être fait avec, ce qui donne lieu au troisième point ci-dessus . Pour cette raison, la documentation de l'API doit se concentrer sur l'explication de la manière d'interpréter l'hypertexte contenu dans la réponse.

De plus, chaque fois qu'un URI vers une ressource Foo est demandé, la réponse contient toutes les informations nécessaires à un agent pour découvrir comment procéder, par exemple en accédant aux ressources associées et parentes via leurs URI, ou en prenant des mesures après la création / suppression d'une ressource.

La clé de tout le système est que la réponse consiste en un hypertexte contenu dans un type de média qui lui-même transmet à l'agent des options pour continuer. Ce n'est pas sans rappeler la façon dont un navigateur fonctionne pour les humains.

Mais ce n'est que ma meilleure estimation à ce moment précis.

Fielding a publié un suivi dans lequel il a répondu aux critiques selon lesquelles sa discussion était trop abstraite, manquait d'exemples et riche en jargon:

D'autres essaieront de déchiffrer ce que j'ai écrit de manière plus directe ou applicable à une préoccupation pratique d'aujourd'hui. Je ne le ferai probablement pas, car je suis trop occupé à m'attaquer au sujet suivant, à préparer une conférence, à écrire un autre standard, à voyager dans un endroit éloigné ou à faire simplement les petites choses qui me donnent l'impression d'avoir gagné mon chèque de paie.

Donc, deux questions simples pour les experts REST avec un état d'esprit pratique: comment interprétez-vous ce que dit Fielding et comment le mettez-vous en pratique lors de la documentation / mise en œuvre des API REST?

Edit: cette question est un exemple de la difficulté d'apprendre quelque chose si vous n'avez pas de nom pour ce dont vous parlez. Le nom dans ce cas est "Hypermedia comme moteur de l'état d'application" (HATEOAS).


26
John, Rich explique simplement le changement de mentalité qu'il a eu. Il n'y a rien de subjectif ou d'argument à ce sujet. Votez pour rester ouvert - c'est l'une des meilleures questions étiquetées `` repos '' que j'ai vues sur SO.
Keith Gaughan

4
Keith, «expliquer le changement de mentalité» est quelque chose qu'il devrait faire dans son blog, pas sur SO.
John Saunders

13
Il n'explique pas son changement de mentalité, il demande si sa compréhension est exacte.
aehlke le

4
Excellent résumé. J'ai appris plus de cette question que de la plupart des réponses.
Martin Konecny

Réponses:


21

Je pense que votre explication le couvre principalement. Les URI sont des identifiants opaques qui, pour la plupart, ne devraient pas être communiqués au-delà de l'URI du signet utilisé par l'agent utilisateur pour accéder à l'application.

Quant à la documentation, cette question a été posée plusieurs fois. Vous documentez votre type de média, ainsi que les contrôles d'hyperlien qu'il contient (liens et formulaires), et le modèle d'interaction si vous le souhaitez (voir AtomPub).

Si vous documentez les URI ou comment les construire, vous le faites mal.


Est-ce toujours vrai? Il existe des spécifications de réponse API comme Ionspec qui ont fait ces URI dans le cadre de la réponse intentionnellement.
Sean Pianka

Oui ils ont. À ce stade, il s'agit de déterminer si ces URI documentés ne sont que des points d'entrée de l'application, qui sont garantis de rester (certains d'entre eux ne sont pas rares et assez utiles) ou si, parce que les gens veulent la génération de code, ceux-ci sont intégrés à partir de une spécification directement dans le code, empêchant le serveur de faire savoir au client comment il peut faire les choses. Si le client pense qu'il sait grâce à ce contrat, vous n'êtes pas dans l'hypermédia, vous êtes dans le modèle de savon openapi moderne, avec les mêmes problèmes que vous auriez rencontrés il y a 18 ans.
SerialSeb

Ce qui est vrai, c'est que de nombreux langages de documentation d'API ont vu le jour au cours des 11 dernières années, mais les fondamentaux n'ont pas changé. Je pense que la découverte de ces liens, ou à tout le moins de la découverte de modèles d'URI, a pour valeur de créer un code client générique réutilisable qui peut les utiliser de manière dynamique, permettant à de nombreuses implémentations côté serveur de réutiliser le même code client. L'intégration d'URI continue de rendre de tels scénarios plus difficiles, mais si vous utilisez ces formats, vous avez tendance à coupler étroitement un client généré à partir de ces spécifications, vous avez donc déjà perdu cette fonctionnalité.
SerialSeb

8

Votre interprétation me semble correcte. Je pense que les contraintes de Fielding peuvent être appliquées dans la pratique.

J'aimerais vraiment voir quelqu'un publier de bons exemples sur la façon de documenter une interface REST. Il y a tellement d'exemples médiocres, il serait très utile d'en avoir quelques-uns valides pour orienter les utilisateurs.


2
Sensationnel. Cette page du modèle de ressources m'a fait pleurer. Espérons que cela lance une tendance.
Darrel Miller

C'est dommage que ce soit fondamentalement le seul exemple d'une telle API sur le web! Pire encore, il n'y a pas du tout de bons exemples de code client qui suit le principe (que j'ai trouvé).
jkp

1
@DarrelMiller Mais ces types de médias ne sont-ils pas trop "spécifiques"? Il me semble que leur API n'utilise vraiment qu'un seul MIME:, application/jsonet que les modèles de ressources sont vraiment les relations. Ai-je mal compris cet aspect de REST? J'ai également lu une de vos réponses SO qui semble indiquer que ces contrats "à un attribut" devraient être évités ...
edsioufi

2
@RichApodaca Votre lien est mort de dysenterie. web.archive.org/web/20170409132237/https://kenai.com/projects/…
forresthopkinsa

5

J'ai recherché un bon exemple d'API écrite suivant le HATEOAS et j'ai eu du mal à en trouver une (j'ai trouvé que l'API SunCloud et AtomPub étaient difficiles à appliquer à une situation d'API "normale"). J'ai donc essayé de faire un exemple réaliste sur mon blog qui suivait les conseils de Roy Fieldings sur ce que signifie être une implémentation REST appropriée. J'ai trouvé très difficile de trouver l'exemple, malgré le fait qu'il soit assez simple en principe (juste déroutant lorsque vous travaillez avec une API par opposition à une page Web). Je comprends ce que Roy contestait et je suis d'accord, c'est juste un changement d'état d'esprit à mettre en œuvre correctement pour une API.

Jetez un œil: Exemple d'API utilisant Rest


4

La seule exception à donner des instructions sur la façon de construire des URI est qu'il est permis d'envoyer un modèle d'URI dans la réponse hypertexte, avec des champs à remplacer automatiquement par le client, en utilisant d'autres champs dans l'hypertexte. Cela ne finit généralement pas par économiser beaucoup de bande passante puisque la compression gzip gérera assez bien les parties répétées des URI pour ne pas s'en soucier.

Quelques bonnes discussions sur REST et les HATEOAS associés:

Avantages de (également) l'utilisation de HATEOAS dans les API RESTFul

Comment obtenir une tasse de café



4

Ce que la plupart des gens se trompent, c'est que (du moins je pense) dans le monde REST, vous ne documentez pas votre "interface de repos", ce que vous documentez est un type de média, indépendamment de votre serveur ou service.


2

Je pense qu'au fil des années où REST existe maintenant, les technologues ont accepté le concept de ressource et ce qui est vraiment REST ou non.

Selon le modèle de maturité de Richardson, il existe 4 niveaux (0-3) qui définissent le degré de REST de votre API, 3 signifiant une API véritablement RESTful, tout comme Roy Fielding l'a voulu.

Le niveau 0 est lorsque vous avez un URI de point d'entrée - comme SOAP.

Le niveau 1 signifie que l'API est capable de faire la distinction entre différentes ressources et a plus d'un point d'entrée - sent toujours SOAP.

Le niveau 2 est lorsque vous utilisez des verbes HTTP - GET, POST, DELETE principalement. C'est le niveau auquel REST entre vraiment en scène.

Au niveau 3, vous commencez à utiliser des contrôles hypermédia pour rendre votre API véritablement REST.

Liens suggérés pour plus de lecture:


1

Absolument correct. Je noterais en outre que ces modèles d'URI conviennent parfaitement dans une application RESTful tant que les modèles proviennent de documents reçus du serveur (OpenSearch étant un exemple approprié). Pour les modèles d'URI, vous documentez où ils sont utilisés et quels sont les espaces réservés attendus dans le modèle, mais pas les modèles eux-mêmes. Légèrement contrairement à ce que Wahnfrieden a dit, ce n'est pas une exception.

Par exemple, à mon travail, nous avons un système de gestion de domaine interne, et le document de service spécifie deux modèles d'URI: un pour produire un URI de meilleure estimation pour une ressource de domaine, et un autre pour construire un URI pour interroger la disponibilité du domaine. Il est toujours possible de parcourir la collection de domaines pour déterminer quel est l'URI d'un domaine donné, mais étant donné le nombre immense de domaines qu'il gère, cela ne serait pas faisable pour le client, ce qui lui donne un moyen de deviner ce que le L'URI d'une ressource de domaine pourrait être une énorme victoire en termes de facilité de mise en œuvre du point de vue du client et de bande passante du serveur.

À votre question: notre documentation normative est exposée aux ressources, à l'effet de diverses méthodes sur ces ressources, aux types de supports de représentation utilisés et à leurs schémas, et au type de ressources vers lesquelles les URI dans ces représentations pointent.

Nous incluons également une documentation non normative (informative) qui a attaché une clause de non-responsabilité pour ne pas trop lire dans les URI mentionnés dans le document, qui donne des exemples d'interactions client-serveur typiques. Cela met la documentation normative plutôt abstraite en termes concrets.


1
C'est bien de fournir des modèles d'URI dans le cadre de votre API, hors bande. VEUILLEZ simplement ne pas appeler cela REST, car ce n'est pas le cas. C'est une énorme quantité de couplage, et exactement ce que REST a été conçu pour éviter. Mais comme vous le dites, REST n'est pas pour toutes les applications. Alors ne prétendez pas que chaque application est REST.
aehlke le

1
En fait, je suis d'accord. Je crois que c'est ce que j'ai dit. Cependant, je ne vois vraiment aucune bonne raison de fournir des modèles d'URI hors bande.
Keith Gaughan

0

Supposons que GET /foos/createFormsoit invoqué pour obtenir les valeurs des champs de formulaire pour lesquelles il faut fournir lorsque nous allons créer POST /foos. Maintenant, cette URL particulière, c'est-à-dire celle utilisée pour créer des foos, devrait être mentionnée dans la réponse GET /foos/createFormcomme lien d'action de soumission selon la proposition de Fielding, n'est-ce pas?
Alors quel est l'avantage de mapper des actions à des verbes Http bien connus en actions, la chose «convention sur code / config» est annulée.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.