Démystifier le repos

Non, ce n'est pas un article qui vous encourage à dormir plus! Cependant, si c’était votre première inclination, le texte suivant était fait sur mesure pour vous! Malheureusement, les principes de REST sont résolument complexes. Des livres entiers ont été écrits sur le sujet. Je ne serai pas si présomptueux de supposer que je peux fusionner un sujet aussi complexe en quelques milliers de mots.

Cela dit, REST, comme certaines autres technologies, telles que Git et CSS, est une technologie dans laquelle une bonne compréhension vous mènera loin. Pour aller aussi vite que possible, cet article se concentrera moins sur l'histoire et la philosophie de REST (ainsi que sur la façon dont il diffère d'autres technologies, telles que SOAP), mais davantage sur les aspects pratiques. Comment pouvez-vous mettre en œuvre l'architecture REST aujourd'hui?


Qu'est-ce que le repos??

Attends là, partenaire. Avant de pouvoir passer à quelques exemples de code, nous devons d’abord discuter de ce que REST, ou Representational State Transfer, désigne:.

REST, défini il y a plus de dix ans par Roy Fielding dans sa thèse de doctorat, offre un moyen simple d'organiser les interactions entre les systèmes, le plus souvent via HTTP et le navigateur Web. Avec le recul, cette cohésion est parfaitement logique: Roy est également l’un des principaux auteurs de HTTP.!

Discutons des adresses URI un instant. Un URI est essentiellement un identifiant pour une ressource. Prenons l'exemple suivant:

GET / amis

Nous pourrions appeler cela une ressource. Lorsque cette route est déclenchée, suivant le modèle REST, tous les amis doivent être récupérés, probablement depuis une base de données, et présentés..

Mais, comment pourrions-nous spécifier une demande pour un seul ami? Que diriez-vous:

GET / amis / joe

Lisible, n'est ce pas? C'est l'un des composants clés d'une architecture RESTful. Il permet de créer des structures URI lisibles de manière égale par les humains et les machines..

Pensez à une ressource comme un nom pluriel. Contacts, statuts, utilisateurs, photos - tout cela serait un choix parfait.

Jusqu'à présent, nous avons des crochets pour identifier une collection, ainsi qu'un seul élément dans cette collection:

/ amis / amis / joe

En fait, vous constaterez que ces deux segments sont tout ce dont vous auriez besoin! Nous pouvons ensuite utiliser la puissance de HTTP pour indiquer comment le serveur doit répondre à ces URI. Laisse-moi expliquer:

Chaque demande HTTP spécifie une méthode, ou un verbe, dans les en-têtes. Vous connaissez probablement quelques-uns d'entre eux, tels que OBTENIR et POSTER. Peut-être un exemple est en ordre. Ouvrez Google Chrome et accédez à http://net.tutsplus.com. Ensuite, ouvrez les Outils de développement Chrome (via un clic droit) et affichez l'onglet Réseau. Il se peut que vous deviez éventuellement actualiser la page pour afficher les divers actifs extraits. Sélectionnez le premier élément de la liste et affichez les en-têtes..

"Les outils de développement de Google Chrome permettent, entre autres, d'inspecter les en-têtes d'une requête donnée."

Attends une minute; même si nous ne l'avons pas spécifié, la méthode de la requête, OBTENIR, a été réglé automatiquement! On peut en déduire (cher Watson) que OBTENIR est le verbe par défaut lors de la visualisation de pages Web.

Pour tout URI donné, nous pouvons faire référence à quatre méthodes de requête différentes: OBTENIR, POSTER, METTRE, et EFFACER.

GET / amis POST / amis PUT / amis DELETE / amis

Essentiellement, ces verbes HTTP indiquent au serveur quoi faire avec les données identifiées par l'URI. Encore confus? Tu devrais être! Un moyen facile de déchiffrer ces verbes est de les comparer au sigle CRUD courant, ou créer-lire-mettre à jour-supprimer.

GET => READ POST => CREATE PUT => UPDATE DELETE => DELETE

Nous avons établi que OBTENIR est la méthode de requête par défaut, mais vous êtes certainement familier avec POSTER ainsi que. Avez-vous déjà créé un formulaire HTML qui, une fois soumis, POSTEREst-ce que les données sont sur votre serveur? Eh bien, lorsque ce formulaire est soumis, la méthode de requête utilisée est POSTER, ne pas OBTENIR. Par exemple, pour ajouter un nouveau statut à une table de tweets dans votre base de données, le formulaire doit POSTER à / tweets, plutôt que quelque chose le long des lignes de /tweets/addNewTweet.php.

En fait, pour une application non-RESTful, la recherche de verbes dans l'URI est une sonnerie inutile. La méthode de requête HTTP doit définir la manière dont le serveur doit interagir avec l'URI, et non une masse de fichiers PHP sans signification.!

Tous les éléments suivants représentent des adresses URI non reposantes et mal conçues.

/tweets/addNewTweet.php /friends/deleteFriendByName.php /contacts/updateContact.php

Pour canaliser mon plus jeune moi, beurk! Ne fais pas ça. Cependant, cela soulève la question suivante: quel serait l'URI correct pour présenter un formulaire à un utilisateur, dans le but d'ajouter ou de modifier une ressource??

Dans ces situations, il est logique d’ajouter deux autres URI..

GET / friends / nouveau GET / friends / joe / edit

Le premier chemin, / amis / nouveau, devrait présenter un formulaire à l'utilisateur pour ajouter un nouvel ami. Lors de la soumission du formulaire, un POSTER demande devrait être utilisé, comme nous ajoutons un nouvel ami.

Pour la seconde, / amis / joe / modifier, Ce formulaire doit être utilisé pour éditer un enregistrement existant dans notre base de données. Lors de la mise à jour d'une ressource, une requête PUT est appropriée..

Vous vous demandez comment faire METTRE demandes d'un formulaire HTML? Restez à l'écoute.


Verbes

Avant de poursuivre avec quelques exemples de code concrets, précisons ce que chacun de ces verbes représente..

OBTENIR

Comme noté précédemment, OBTENIR est le HTTP méthode de requête que nous connaissons le mieux: le verbe par défaut. Une mise en garde, ou meilleure pratique, en matière de OBTENIR demandes, est qu'ils doivent toujours être traités comme sûr et idempotent. En d'autres termes, un OBTENIR La requête doit être "en lecture seule".

Il est important de noter qu'en tant qu'ingénieur, vous êtes libre de faire ce que vous voulez, lorsque ces itinéraires sont déclenchés. Rien ne vous empêche de modifier les données sur le serveur, quand un OBTENIR la demande est déclenchée. C'est simplement une bonne pratique de s'abstenir de le faire.

Une méthode sûre fait référence à une méthode qui ne modifiera jamais une ressource. Le terme idempotent fait référence à une méthode qui aboutira au même résultat, quel que soit le nombre de demandes demandées.. OBTENIR, METTRE, et EFFACER les types de requête sont idempotents - c'est-à-dire si vous suivez les règles.

POSTER

La deuxième méthode de requête que vous connaissez probablement est POSTER. De nos jours, ce type est le plus souvent utilisé pour désigner le moment où de nouvelles données doivent être ajoutées à une ressource. Par exemple, lors de l'ajout d'un nouvel ami, une méthode POST serait le bon choix.

POST / amis

METTRE

Traditionnellement, un METTRE request doit être utilisé lorsque vous devez créer ou mettre à jour une ressource. Cependant, peut-être le résultat des conventions de Ruby on Rails, dans la plupart des applications Web modernes, METTRE est utilisé exclusivement pour mettre à jour une ressource.

Imaginons que nous devions mettre à jour l'âge de notre ami Joe. Lors de la mise à jour de ses informations, via un formulaire, la méthode de requête correcte serait, METTRE.

EFFACER

Comme vous l'avez peut-être deviné, EFFACER doit être utilisé lorsque vous devez supprimer la ressource identifiée par un URI particulier.

Si nous ne sommes plus amis avec Susan, en suivant les principes de REST, elle peut être détruite, via un EFFACER demande.

SUPPRIMER / amis / susan

Une fois exécutées, toutes les données associées à Susan doivent être supprimées de la base de données..


la mise en oeuvre

Toute cette théorie est excellente, mais au final, elle est inutile si nous ne comprenons pas comment appliquer cette architecture à nos projets. Eh bien, il y a plusieurs façons. Dans la section suivante, nous utiliserons le populaire framework Slim PHP pour organiser le routage nécessaire. Cependant, vous constaterez sûrement que la plupart des frameworks incluent une forme d'intégration RESTful, notamment Ruby on Rails et Laravel.

Pour utiliser Slim, la première étape consiste à l'installer via Composer..

“Composer est un outil de gestion de la dépendance en PHP. Il vous permet de déclarer les bibliothèques dépendantes dont votre projet a besoin et les installera dans votre projet pour vous..

Attendez, vous n'êtes pas familier avec Composer? Arrêtez ce que vous faites maintenant et faites des recherches. Composer nous permet de tirer parti de la communauté PHP en spécifiant et en installant les packages nécessaires à une application. Ne réinventez plus la roue!

L'installation globale de Composer ne nécessite que deux commandes rapides.

$ curl -s https://getcomposer.org/installer | php $ sudo mv composer.phar / usr / local / bin / composer

C'est tout! Vous avez maintenant accès au compositeur commander.

L'étape suivante consiste à spécifier Slim en tant que package requis pour votre application. Ceci peut être accompli, via un fichier composer.json à la racine de votre projet.

"require": "slim / slim": "2. *"

Avec cette exigence définie, nous avons seulement besoin de courir compositeur installer télécharger les dépendances nécessaires. Facile!

Grâce à quelques lignes de code et à la communauté PHP, nous disposons désormais d’une manière élégante d’enregistrer des itinéraires. Voici un exemple simple, que vous pouvez placer dans index.php.

get ('/ friends', function () echo 'Récupération de tous les amis';); $ app-> run ();

Rappelez-vous: toute cette fonctionnalité est gratuite!

«Slim est un micro-framework PHP qui vous aide à écrire rapidement des applications Web et des API simples mais puissantes..

Réglons maintenant les routes de ressources nécessaires. Nous allons opter pour simple écho déclarations pour décrire quel type d'action doit être exécuté dans une application du monde réel.

get ('/ friends', function () echo 'Récupère tous les amis';); $ app-> get ('/ amis / nouveau', function () echo 'Afficher le formulaire pour ajouter un nouvel ami'; // le formulaire doit être envoyé à / amis); $ app-> get ('/ friends /: friend', fonction ($ friend) echo 'Afficher un ami unique:'. $ friend;); $ app-> get ('/ amis /: ami / modifier', fonction ($ ami) echo 'Afficher le formulaire pour modifier un ami' // Le formulaire doit être placé dans / amis / $ ami); $ app ->; post ('/ friends', function () echo 'Ajouter un nouvel ami';); $ app ->; put ('/ amis /: ami', fonction ($ ami) echo 'Mettre à jour un ami';); $ app ->; delete ('/ friends /: friend', fonction ($ friend) echo 'Supprimer un ami';); $ app ->; run ();

Lorsque vous utilisez Slim, nous pouvons spécifier la méthode de requête à laquelle nous souhaitons répondre, en utilisant $ app-> VERBE. En tant que tel, pour supprimer l'ami, Joe, nous écouterions un effacer demande à / amis / joe, ainsi:

$ app-> delete ('/ amis /: ami', fonction ($ ami) echo 'Détruire un ami';);

Itinéraires d'essai

Si vous êtes comme moi, votre prochaine pensée pourrait porter sur la façon dont vous êtes censé tester METTRE et EFFACER méthodes. Comme vous le savez peut-être, la plupart des navigateurs ne prennent en charge que nativement OBTENIR et POSTER. L'utilisation des deux autres méthodes de requête nécessite un peu de ruse, que nous examinerons bientôt..

Jusque-là, le moyen le plus convivial de formuler des demandes personnalisées consiste à utiliser une extension Google Chrome, appelée Advanced Rest Client. Une fois installé, vous pouvez facilement spécifier un URI, ainsi que la méthode de requête souhaitée..

“Les extensions du client REST avancé offrent un mécanisme simple pour tester les URI.

boucle

Si vous êtes un peu à l'aise dans la ligne de commande, il est recommandé d'utiliser plutôt la puissance de cURL pour tester ces itinéraires..

curl localhost: 8888 / friends -X GET

la X flag vous permet de spécifier la méthode de requête à utiliser. Notez que dans l'extrait précédent, nous sommes explicites. la X le drapeau n'est pas nécessaire pour OBTENIR les demandes, car elles sont la valeur par défaut.

Voici un exemple pour tester quelques itinéraires. Gardez à l'esprit que nous utilisons simple écho déclarations pour décrire l'action qui devrait avoir lieu.

$ curl localhost: 8888 / friends -X OBTENIR Tous les amis $ curl localhost: 8888 / friends -X POST -d 'name = Jane & age = 30' Ajouter un nouvel ami $ curl localhost: 8888 / friends / jane -X PUT -d 'name = Jane & age = 28' Mettre à jour une amie, Jane $ curl localhost: 8888 / friends / jane -X SUPPRIMER See ya, Jane

La modification des données sur le serveur nécessitera sûrement les nouvelles données (probablement obtenues à partir d'un formulaire). Lors de l’utilisation de cURL, des paires clé-valeur peuvent être spécifiées à l’aide de la touche -ré drapeau, comme si:

$ curl localhost: 8888 / friends -X POST -d 'nom = Jane & age = 30'

Cette commande peut être divisée en trois parties:

  1. Quel est l'URI?
  2. Quelle méthode de requête doit être utilisée?
  3. Quelles données doivent être transmises au serveur?

En utilisant la langue de votre choix côté serveur (dans notre cas, PHP), vous pouvez ensuite aller chercher cette POSTER données de la même manière que vous le feriez normalement:

$ app-> post ('/ friends', function () $ name = $ _POST ['name']; // Jane $ age = (int) $ _POST ['age']; // 30 // Maintenant, mettre à jour la base de données);

Prise en charge du navigateur

Bien, nous comprenons comment spécifier une méthode de requête à partir de la ligne de commande, mais comment pourrions-nous faire la même chose à partir d'un formulaire HTML? Malheureusement, nous ne pouvons pas compter sur:

Notre génération actuelle de navigateurs ne fournit pas de support natif pour ces types de demandes. La solution la plus courante consiste à appliquer un peu de ruse, via des entrées cachées. En utilisant le framework Slim, voici comment mettre à jour un ami.

 … D'autres champs de formulaire ici…   

Notez que, techniquement, la méthode de requête est toujours définie sur POSTER. Cependant, en coulisse, Slim lit la valeur de l'entrée masquée et procède en conséquence, en fonction du verbe spécifié..

Vous constaterez certainement que la plupart des frameworks suivent un modèle similaire pour spécifier les types de requête..

Dans cette section, nous n’avons examiné que la mise en œuvre du routage avec ressources par un seul cadre. Comme vous le constaterez, la même chose est possible dans la plupart des cadres de nos jours. Par exemple, si vous êtes un artisan Laravel, vous pouvez utiliser la syntaxe suivante (à partir de la version 4):

Route :: resource ('friends', 'FriendsController');

Cette méthode de ressource pratique spécifie que nous souhaitons générer les routes nécessaires pour une copains ressource et faire AmisContrôleur responsable de la gestion de la logique pour chacune de ces routes.


Mise en œuvre manuelle

Si vous souhaitez vous désinscrire d'un framework, vous pouvez toujours implémenter vous-même cette fonctionnalité. Malheureusement, l'écriture du système de routage nécessaire à partir de zéro n'entre pas dans le cadre de ce didacticiel. Cependant, voici quelques conseils pour vous aider à démarrer..

Tout d’abord, la question la plus importante: comment déterminer le verbe associé à une requête donnée? Si vous continuez, créez un nouveau fichier PHP et ajoutez:

 

Si vous exécutez cette page dans le navigateur, le résultat devrait être OBTENIR. Excellent! Maintenant, nous avons les moyens nécessaires pour détecter la méthode de requête, et procéder, au besoin.

L'extrait suivant est décidément élémentaire et nécessitera une meilleure structure pour vos projets, mais il peut être utilisé comme point de départ.

# Quelle méthode de requête? $ verb = $ _SERVER ['REQUEST_METHOD']; // GET # Qu'est-ce que l'URI? $ uri = substr ($ _ SERVER ['REQUEST_URI'], 1); // friends / joe # Crée un tableau des segments $ segments = explode ('/', $ uri); // ['amis', 'joe'] # Détermine le nom du contrôleur $ controller = $ segments [0]; // amis // Procédez au besoin, en fonction du type de requête switch ($ verb) case 'GET': case 'POST': case 'PUT': case 'DELETE':

Essai

Il existe une variété de packages qui simplifient au maximum la rédaction des tests d'intégration. Cependant, restons simples et utilisons la bibliothèque intégrée cURL de PHP (libcurl) pour tester certaines de ces routes.

La première étape consiste à initialiser cURL et à spécifier l'URI souhaité. Dans notre cas, nous allons continuer à tester le copains Ressource.

# Init curl et spécifiez l'URI $ ch = curl_init ('localhost: 8888 / friends');

Ensuite, sauf si nous testons la valeur par défaut OBTENIR méthode de requête, nous devrons spécifier le type de requête.

# Spécifiez le verbe HTTP (nous ignorons les données pour le moment) curl_setopt ($ ch, CURLOPT_CUSTOMREQUEST, 'POST');

Par défaut, cette sortie sera immédiatement répercutée. Pour renvoyer la sortie à une variable plutôt que de l'afficher directement, nous pouvons utiliser le CURLOPT_RETURNTRANSFER réglage.

// Retourne la sortie au lieu de l'afficher directement curl_setopt ($ ch, CURLOPT_RETURNTRANSFER, true);

Ça devrait le faire! Nous avons seulement besoin d'exécuter la demande et d'extraire les résultats.

$ response = curl_exec ($ ch); // Ajouter un nouvel ami $ statusCode = curl_getinfo ($ ch) ['http_code']; // 200

PHPUnit

Ajoutons ceci à un test PHPUnit - encore une fois, en le gardant relativement simple, par souci de lisibilité. Nous veillerons simplement à ce que chaque itinéraire renvoie le bon 200 code de statut, indiquant que la demande s'est terminée avec succès. Pour faire le ménage, nous allons résumer la fonctionnalité cURL à sa propre méthode, demande().

request ('amis', 'GET'); $ this-> assertEquals ('200', $ request-> statusCode);  fonction publique testUpdateFriend () $ request = $ this-> request ('friends / frank', 'PUT'); $ this-> assertEquals ('200', $ request-> statusCode);  demande de fonction protégée ($ url, $ verb = 'GET') $ ch = curl_init ($ this-> baseUrl. $ url); curl_setopt ($ ch, CURLOPT_CUSTOMREQUEST, $ verb); curl_setopt ($ ch, CURLOPT_RETURNTRANSFER, true); $ response = new stdClass; $ response-> data = curl_exec ($ ch); $ response-> statusCode = curl_getinfo ($ ch) ['http_code']; return $ response; 

En supposant que PHPUnit soit installé, lancez phpunit friendsTest.php. En cas de succès, vous devriez voir le vert! N'hésitez pas à vous engager dans une danse de victoire privée.

Pour aller plus loin, il est logique d’abstraire que demande méthode sur une classe de base que vos tests peuvent ensuite étendre. Ou encore mieux, laissez un outil tiers hautement testé (et fonctionnel) gérer les démarches. Vous pouvez envisager Goutte, qui peut être installé via Composer.

"require": "slim / slim": "2. *", "fabpot / goutte": "1.0.*@dev"

Une fois installé (compositeur installer), nous pouvons ignorer l'implémentation manuelle de cURL précédemment et utiliser à la place l'API de nettoyage de Goutte, comme illustré ci-dessous:

client = nouveau client;  fonction publique testFriendsCollection () $ this-> client-> request ('GET', 'http: // localhost: 8888 / friends'); $ response = $ this-> client-> getResponse (); $ this-> assertEquals ('200', $ response-> getStatus ());  fonction publique testAddFriend () $ this-> client-> request ('POST', 'http: // localhost: 8888 / friends', []); $ response = $ this-> client-> getResponse (); $ this-> assertEquals (200, $ response-> getStatus ()); 

Vous ne seriez pas la première personne à considérer ces tests comme superflus; Cependant, je vous assure que, dès que l'un de ces tests échouera pour vous éviter une erreur stupide, vous en reconnaîtrez immédiatement l'utilité..


Apprentissage ultérieur

Pour poursuivre vos études, le meilleur guide pour apprendre à utiliser REST est une gracieuseté des employés d’Apigee. Leur présentation, «Apprendre à un chien à se reposer», rassemble une masse de connaissances en seulement vingt minutes. Ceci est obligatoire pour tous les débutants.

“Apigee est l’une des introductions les plus conviviales de REST sur le Web..

Merci d'avoir lu!