Introduction à REST : l’exemple de l’API WordPress

février 08, 2015  |   Actualités,Blog   |     |   2 commentaires

Introduction

Une fois n’est pas coutume, cet article ne va pas parler directement de réseau ou de sécurité mais va aborder un sujet sur le développement : les API RESTful.

Comme on a pu le voir avec nos précédents articles sur le SDN ou OpenStack par exemple, le réseau va devenir de plus en plus programmable et l’infrastructure automatisable. Pour cela on ne configure plus manuellement les équipements via une GUI ou une CLI, mais ce sont des outils d’orchestration, des scripts ou autre, qui vont directement communiquer avec eux via des API. L’ingénieur réseau et sécurité de demain doit donc avoir, en plus de ses connaissances classiques, les notions de développement nécessaires à la maitrise de ces technologies.

REST

REST signifie Representational State Transfer, et a été décrit par Roy T. Fielding dans sa thèse Architectural Styles and the Design of Network-based Software Architectures

C’est un style d’architecture web défini par 6 contraintes :

  • interface uniforme : utilisation du protocole HTTP
  • client-serveur : séparation des problématiques du client (interface utilisateur, contexte) et du serveur (stockage des données)
  • sans état : chaque requête doit contenir toutes les informations nécessaires à son traitement, sans que le serveur aie connaissance des précédentes.
  • cache possible : le client doit pouvoir utiliser un cache pour améliorer les performances
  • systeme en couche : architecture à plusieurs étages possible (proxy, serveurs de cache etc.)
  • code à la demande : optionnellement, du code peut être exécuté par le client (javascript par exemple)

L’objectif ici n’est pas de détailler tous ces concepts (pour cela on peut lire wikipedia) mais d’essayer de comprendre ce que cela implique en pratique avec un exemple concret.

Tout d’abord, une application RESTful, c’est-à-dire qui respecte les principes REST, est basée sur les ressources, plutôt que sur les actions.

Une ressource est tout ce qui peut être référencé par une URL. C’est un concept abstrait qui peut représenter ce que l’on veut (documents, images, ensembles d’autres ressources, etc.)

Ces ressources sont hiérachisées et accessibles via des URLs.

Pour définir les actions à appliquer sur ces ressources, les principales méthodes HTTP utilisées sont :

  • GET : lire une ressource
  • POST : créer une ressource
  • PUT/PATCH : mettre à jour une ressource
  • DELETE : supprimer une ressource

L’exemple de l’API WordPress

Historiquement, WordPress possédait une API XML-RPC. Ce n’est pas une API RESTful, mais une API qui utilise Remote Procedure Call (RPC) et un formatage XML

Wordpress dispose d’une API REST JSON, nommée “WP API”, disponible pour l’instant sous la forme d’un plugin, et qui sera prochainement intégrée au core (prévu pour la version 4.3)
Voyons un peu comment cela fonctionne, si l’on veut par exemple récupérer l’article numéro 25.
Avec l’API XML-RPC, il y a une seule URL pour toutes les requêtes, en général /xmlrpc.php
On envoie une requête HTTP contenant dans le corps, l’appel à la methode “wp.getPost”

<methodCall>
   <methodName>wp.getPost</methodName>
   <params>
      <param><value>1</value></param>
      <param><value>username</value></param>
      <param><value>password</value></param>
      <param><value>25</value></param>
   </params>
</methodCall>

Cette API ne respecte pas REST, car l’URL ne représente pas une ressource, et la méthode HTTP POST est utilisée indifféremment quelque soit l’action (consultation, modification ou création)
Si l’on utilise l’API REST, le fonctionnement est différent

Un des principes REST est que les URLs doivent représenter des ressources. Par exemple pour accéder en lecture à l’article avec l’ID 25, il suffit d’appeler l’URL qui correspond :

curl http://example.com/wp-json/posts/25

Le serveur nous renvoie la représentation de cette ressource au format JSON :

[{
   "ID": 25,
   "title": "Article numero 25",
   "status": "publish",
   "type": "post",
   "author": {
      "ID": 1,
      "name": "admin",
      "slug": "admin",
      "URL": "",
   }
[...]
}]

La sortie est tronquée pour plus de lisibilité

REST n’impose pas le format de représentation des ressources. Cela pourrait aussi bien être du XML ou un autre format, même si JSON est très prisé pour cela.

Si l’on veut modifier notre article, on peut envoyer une requête PUT à la même URL avec par exemple le corps suivant :

{
"title": "Mon nouveau titre",
"content_raw": "<p>Avec du contenu<\/p>",
}

Ainsi on modifie le titre et le contenu de l’article grâce à cette requête PUT

De la même façon une requête DELETE va permettre de supprimer notre article, et une requête POST permettrait d’en créer un nouveau.

Il y a bien sûr d’autres ressources que les articles qui sont disponibles, une requête GET sur /wp-json permet de connaître toutes les “routes” (i.e. les URLs accessibles) et les “endpoints” (les actions ou méthodes associées ) de l’API

curl http://example.com/wp-json/
{
   "name": "My WordPress Site",
   "description": "Just another WordPress site",
   "URL": "http:\/\/example.com",
   "routes": {
      "\/": {
         "supports": [
            "HEAD",
            "GET"
         ],
      "meta": {
         "self": "http:\/\/example.com\/wp-json\/"
        }
   },
   "\/posts": {
      "supports": [
         "HEAD",
         "GET",
         "POST"
      ],
      "meta": {
         "self": "http:\/\/example.com\/wp-json\/posts"
      },
      "accepts_json": true
   },
   "\/posts\/<id>": {
      "supports": [
         "HEAD",
         "GET",
         "POST",
         "PUT",
         "PATCH",
         "DELETE"
],
"accepts_json": true
},
        "\/posts\/\/revisions": {
            "supports": [
                "HEAD",
                "GET"
            ]
        },
        "\/posts\/\/comments": {
            "supports": [
                "HEAD",
                "GET",
                "POST"
            ],
            "accepts_json": true
        },
        "\/posts\/\/comments\/": {
            "supports": [
                "HEAD",
                "GET",
                "POST",
                "PUT",
                "PATCH",
                "DELETE"
            ],
            "accepts_json": true
        },
        "\/posts\/types": {
            "supports": [
                "HEAD",
                "GET"
            ],
            "meta": {
                "self": "http:\/\/example.com\/wp-json\/posts\/types"
            }
        },
[...]

La sortie est tronquée pour plus de lisibilité

Conclusion

REST tente d’établir un standard en reprenant les principes qui ont permis au web de se développer : la séparation du client et du serveur, les URLs pour représenter les ressources, et l’utilisation du protocole HTTP. Cela permet de développer plus facilement et de manière générique des clients pour applications REST. Aujourd’hui de nombreux services web offrent une API REST, comme par exemple Twitter, Facebook, le service de stockage d’Amazon S3, ou encore l’API de pilotage de VPS d’OVH.

2 Commentaires pour cet article

    Arnaud
    juin 20th, 2015 on 15 h 51 min

    Bonjour,

    Merci pour cet article très intéressant. Toutefois, je n’ai rien trouvé sur le fait que WordPress embarque de base une API Restful. J’ai testé l’URL sur un WordPress et ça ne fonctionne pas de base, je pense donc que vous utilisez un plugin.

    Pour ceux que ça intéresse, voici un article complet sur l’utilisation de l’API XML-RPC http://blog.wixiweb.fr/wordpress-api-webservices-xmlrpc/

    De ce que j’ai compris, l’API RESTFUL devrait arriver en natif fin 2015 mais ce n’est pas encore le cas aujourd’hui.

    N’hésitez pas si vous avez plus d’infos sur le sujet.

      Julien GUIRLINGER
      juin 25th, 2015 on 14 h 55 min

      Merci pour cette remarque, j’ai corrigé l’article.
      Effectivement, pour l’instant il faut utiliser le plugin pour avoir l’API REST. Il était prévu qu’il soit intégré directement au core WordPress en version 4.1, mais cela a été repoussé à une prochaine version (probablement la 4.3 qui est prévue pour Août 2015).