Je suis un peu triste de voir qu'après plus de 10 ans, il n'y a pas de réponse indiquant vraiment comment une chose telle que demandée dans l'OP pourrait être conçue dans une architecture REST, donc je ressens le besoin de le faire maintenant.
Tout d'abord, qu'est-ce que REST?! L'acronyme REST ou ReST signifie "Representational State Transfer" et définit l'échange de l'état d'une ressource dans un certain format de représentation. Le format de représentation est conforme au type de média négocié. Dans le cas deapplication/html
format de représentation, il peut y avoir un flux de contenu texte au format HTML qui est rendu dans le navigateur, probablement après avoir appliqué une mise en forme de feuille de style pour positionner certains éléments à certains emplacements.
REST est en principe une généralisation du Web navigable que nous connaissons tous, bien qu'il cible toutes sortes d'applications et pas seulement les navigateurs. Par conséquent, de par leur conception, les mêmes concepts qui s'appliquent au Web s'appliquent également à une architecture REST. Une question comme comment réaliser quelque chose d'une manière "RESTful" résout la réponse à la question comment réaliser quelque chose sur une page Web et ensuite appliquer les mêmes concepts sur la couche d'application.
Une calculatrice basée sur le Web peut généralement commencer par une "page" qui vous permet de saisir des valeurs à calculer avant d'envoyer les données saisies au serveur. En HTML, cela est généralement réalisé via des <form>
éléments HTML qui apprennent au client les paramètres disponibles à définir, l'emplacement cible auquel envoyer la demande ainsi que le format de représentation à appliquer lors de l'envoi des données d'entrée. Cela peut ressembler à ceci:
<html>
<head>
...
</head>
<body>
<form action="/../someResource" method="post" enctype="application/x-www-form-urlencoded">
<label for="firstNumber">First number:</label>
<input type="number" id="firstNumber" name="firstNumber"/>
<label for="secondNumber">Second number:</label>
<input type="number" id="secondNumber" name="secondNumber"/>
<input type="submit" value="Add numbers"/>
</form>
</body>
</html>
L'exemple ci-dessus indique qu'il y a deux champs d'entrée qui peuvent être remplis soit par l'utilisateur soit par d'autres automates, et qu'en invoquant l'élément d'entrée de soumission, le navigateur prend soin de formater les données d'entrée dans un application/x-www-form-urlencoded
format de représentation qui est envoyé à l'emplacement cible mentionné via la méthode de requête HTTP spécifiée, POST
dans ce cas. Si nous entrons 1
dans le firstNumber
champ de saisie et 2
dans le secondNumber
champ de saisie, le navigateur va générer une représentation firstNumber=1&secondNumber=2
et l'envoyer en tant que charge utile du corps de la demande réelle à la ressource cible.
La requête HTTP brute envoyée au serveur peut donc ressembler à ceci:
POST /../someResource
Host: www.acme.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 28
Accept: application/html
firstNumber=1&secondNumber=2
Le serveur peut effectuer le calcul et répondre avec une autre page HTML contenant le résultat du calcul, car la demande a indiqué que le client comprend ce format.
Comme Breton l'a déjà souligné, il n'existe pas d'URL ou d'URI "RESTful". Un URI / URL est son propre genre de chose et ne devrait pas donner de sens à un client / utilisateur. Dans l'exemple de calculatrice ci-dessus, un utilisateur n'est tout simplement pas intéressé par l'endroit où lui envoyer les données. Il souhaite simplement que lors du déclenchement du champ d'entrée de soumission, la demande soit envoyée. Toutes les informations requises pour effectuer la tâche doivent déjà être fournies par le serveur.
Un navigateur peut également ne pas être conscient du fait que la demande alimente en fait une calculatrice avec certains paramètres d'entrée, il pourrait aussi bien s'agir d'une sorte de formulaire de commande qui renvoie uniquement la représentation de formulaire suivante pour continuer le processus de commande ou d'un type totalement différent de Ressource. Il effectue simplement ce que la spécification HTML exige dans un tel cas et il se fiche de ce que fait réellement le serveur. Ce concept permet à un navigateur d'utiliser le même format de représentation pour faire toutes sortes de choses telles que commander des choses dans votre boutique en ligne préférée, discuter avec vos meilleurs amis, vous connecter à un compte en ligne, etc.
L' abordabilité de certains éléments, comme dans le cas du champ de saisie de soumission qui est généralement rendu sous forme de bouton, définit ce que vous devez en faire. Dans le cas d'un bouton ou d'un lien, il vous demande essentiellement de cliquer dessus. D'autres éléments peuvent transmettre des opportunités différentes. Une telle possibilité peut également s'exprimer via des relations de lien de , c'est-à-dire avec preload
des liens annotés qui indiquent essentiellement à un client qu'il peut déjà charger le contenu de la ressource liée en arrière-plan, car l'utilisateur saisira très probablement ce contenu ensuite. De telles relations de liens doivent bien sûr être standardisées ou suivre le mécanisme d'extension pour les types de relations tels que définis par les liens Web .
Ce sont les concepts fondamentaux qui sont utilisés sur le Web et qui devraient également être utilisés dans une architecture REST. Selon "l'Oncle Bob" Robert C. Martin, une architecture est une intention et l'intention derrière l'architecture REST est le découplage des clients des serveurs pour permettre aux serveurs d'évoluer librement à l'avenir sans avoir à craindre de casser des clients. Cela nécessite malheureusement beaucoup de discipline car il est si facile d'introduire le couplage ou d'ajouter des solutions rapides pour faire le travail et passer à autre chose. Comme l'a souligné Jim Webber dans une architecture REST, vous, en tant que fournisseur de services, devez essayer de concevoir un protocole d'application de domaine similaire à un jeu informatique textuel des années 70 que les clients suivront jusqu'à la fin d'un processus.
Ce que de nombreuses API dites «REST» font malheureusement en réalité, c'est tout sauf cela. Vous voyez l'échange de données basées principalement sur JSON qui est spécifié dans une documentation externe spécifique à l'API qui est généralement difficile à intégrer dynamiquement à la volée. Le format auquel une demande doit ressembler est également codé en dur dans la documentation externe, ce qui conduit à de nombreuses URI d'interprétation d'implémentation pour renvoyer des types prédéfinisau lieu d'utiliser un format de représentation commun qui est négocié à l'avance. Cela empêche les serveurs de changer car les clients s'attendent maintenant à recevoir un certain format de données (notez pas le format de représentation!) Pour les URI prédéfinis. Cet échange de format de données personnalisé empêche en outre les clients d'interagir avec d'autres API car le "format de données" est généralement associé à une API spécifique. Nous connaissons ce concept du passé grâce aux technologies RPC telles que Corba, RMI ou SOAP que nous condamnons comme étant en quelque sorte maléfiques, même si Peppol y est retourné en remplaçant AS2 par AS4 comme protocole de transfert par défaut récemment.
En ce qui concerne la question posée, l'envoi de données sous forme de fichier csv n'est pas différent de l'utilisation d'une application/x-www-form-urlencoded
représentation ou de choses similaires. Jim Webber a précisé qu'après tout, HTTP n'est qu'un protocole de transport dont le domaine d'application est le transfert de documents sur le Web . Le client et le serveur doivent au moins tous deux prendre text/csv
en charge comme défini dans la RFC 7111 . Ce fichier CSV pourrait être généré à la suite du traitement d'un type de média qui définit des éléments de formulaire, un élément cible ou un attribut auquel envoyer la demande ainsi que la méthode HTTP pour effectuer le téléchargement de la configuration.
Il existe quelques types de supports qui prennent en charge des formulaires tels que HTML , HAL Forms , halform , ion ou Hydra . Je suis actuellement, cependant, pas au courant d'un type de média qui peut automatiquement coder les données d'entrée en text/csv
directement où on pourrait avoir besoin d'être défini et enregistré avec le registre de type de support de l' IANA .
Le téléchargement et le téléchargement du jeu de paramètres complet ne devraient pas être un problème, je suppose. Comme mentionné précédemment, l'URI cible n'est pas pertinent car un client utilisera simplement l'URI pour récupérer le nouveau contenu à traiter. Le filtrage par date ouvrable ne devrait pas non plus être trop difficile. Ici, le serveur doit cependant le client avec toutes les possibilités que le client peut simplement choisir. Ces dernières années, GraphQL et RestQL ont évolué, introduisant un langage de type SQL qui peut être ciblé sur un certain point de terminaison pour obtenir une réponse filtrée. Cependant, dans un vrai sens REST, cela viole l'idée derrière REST comme a) GraphQL c'est-à-dire n'utilise qu'un seul point de terminaison qui empêche en quelque sorte l'utilisation optimale de la mise en cache et b) nécessite la connaissance des champs disponibles à l'avance, ce qui peut conduire à introduire un couplage de clients au modèle de données de base de la ressource.
L'activation ou la désactivation de certains paramètres de configuration est simplement une question de déclenchement des contrôles hypermédia qui offrent cette possibilité. Dans les formulaires HTML, cela peut être une simple case à cocher ou une sélection sur plusieurs lignes dans une liste ou ce genre. Selon le formulaire et la méthode qu'il définit, il pourrait alors potentiellement envoyer la configuration entière via PUT
ou être intelligent sur les modifications effectuées et effectuer uniquement une mise à jour partielle via PATCH
. Ce dernier nécessite essentiellement un calcul de la représentation de changement à celle mise à jour et alimente le serveur avec les étapes requises pour transformer la représentation actuelle en celle souhaitée. Selon la spécification PATH, cela doit être fait dans une transaction afin que toutes ou aucune des étapes ne soient appliquées.
HTTP autorise et encourage un serveur à valider une demande reçue à l'avance avant d'appliquer les modifications. Pour PUT, la spécification stipule:
Un serveur d'origine DEVRAIT vérifier que la représentation PUT est cohérente avec toutes les contraintes du serveur pour la ressource cible qui ne peuvent pas ou ne seront pas modifiées par le PUT. Ceci est particulièrement important lorsque le serveur d'origine utilise des informations de configuration internes liées à l'URI afin de définir les valeurs des métadonnées de représentation sur les réponses GET. Lorsqu'une représentation PUT n'est pas cohérente avec la ressource cible, le serveur d'origine DEVRAIT soit les rendre cohérentes, en transformant la représentation ou en modifiant la configuration de la ressource, soit répondre avec un message d'erreur approprié contenant des informations suffisantes pour expliquer pourquoi la représentation est inadaptée. Les codes d'état 409 (Conflit) ou 415 (Type de support non pris en charge) sont suggérés,
Par exemple, si la ressource cible est configurée pour toujours avoir un Content-Type de "text / html" et que la représentation en cours PUT a un Content-Type de "image / jpeg", le serveur d'origine doit faire l'une des actions suivantes:
une. reconfigurer la ressource cible pour refléter le nouveau type de média;
b. transformer la représentation PUT en un format cohérent avec celui de la ressource avant de l'enregistrer en tant que nouvel état de ressource; ou,
c. rejeter la demande avec une réponse 415 (type de support non pris en charge) indiquant que la ressource cible est limitée à "text / html", y compris peut-être un lien vers une ressource différente qui serait une cible appropriée pour la nouvelle représentation.
HTTP ne définit pas exactement comment une méthode PUT affecte l'état d'un serveur d'origine au-delà de ce qui peut être exprimé par l'intention de la demande de l'agent utilisateur et la sémantique de la réponse du serveur d'origine. ...
Pour résumer ce message, vous devez soit utiliser un type de support existant qui vous permet d'enseigner à un client les paramètres d'entrée requis ou pris en charge, l'emplacement cible auquel envoyer la demande, l'opération à utiliser ainsi que le type de support le La demande doit être formatée ou définir la vôtre que vous enregistrez auprès de l'IANA. Ce dernier peut être nécessaire si vous souhaitez convertir l'entrée entext/csv
puis téléchargez la représentation CSV sur le serveur. La validation doit avoir lieu avant que les modifications ne soient appliquées à la ressource. L'URI réel ne doit pas être pertinent pour les clients autrement que pour déterminer où envoyer la demande et, en tant que tel, peut être librement choisi par vous, le prestataire de services. En suivant ces étapes, vous avez à peu près la liberté de changer votre côté serveur à tout moment et les clients ne se casseront pas en conséquence s'ils prennent en charge les types de supports utilisés.