|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: Créer une API REST |
| 4 | +author: bclozel |
| 5 | +tags: [rest, api] |
| 6 | +published: true |
| 7 | +--- |
| 8 | + |
| 9 | +Les APIs REST sont de plus en plus utilisées: |
| 10 | + |
| 11 | +* avec les webservices dits "techniques" (à usage interne uniquement à |
| 12 | + une plate-forme), qui viennent simplifier l'utilisation de services |
| 13 | +orientés SOAP. |
| 14 | +* avec des APIs orientées "web UI", qui sont utilisées par des |
| 15 | + applications full javascript. |
| 16 | +* pour des APIs orientées applications mobiles ou utilisation par une |
| 17 | + grande variété de développeurs tiers. |
| 18 | + |
| 19 | +Le terme "API REST" est très conceptuel, voire polémique; les concepts |
| 20 | +derrière REST ne sont pas suffisants pour répondre à tous vos besoins. |
| 21 | +Cet article donne quelques pistes pour la conception et la mise en |
| 22 | +oeuvre d'une API de ce type. |
| 23 | + |
| 24 | +Pas besoin de lire [la thèse de Roy |
| 25 | +Fielding](http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm) ou |
| 26 | +de suivre à la lettre tous les dogmes REST - mais quelques règles |
| 27 | +simples ne sont pas à négliger. |
| 28 | + |
| 29 | +## Règle #1: respecter les grands principes REST |
| 30 | + |
| 31 | + GET http://example.org/user/12 |
| 32 | + |
| 33 | +Une API REST doit avant tout servir à manipuler des **ressources** (ici, |
| 34 | +un utilisateur) avec des verbes (ici, GET). Trop souvent, les |
| 35 | +concepteurs d'API ont tendance à inclure des verbes dans les URIs. |
| 36 | + |
| 37 | +L'API Flickr est un bon exemple de pièges à éviter; on retrouve dans les |
| 38 | +URIs des noms de méthodes (en fait, cette API est plus proche de RPC que |
| 39 | +de REST). |
| 40 | + |
| 41 | + GET http://api.flickr.com/services/rest/?method=flickr.photos.delete&api_key=aaabbbccc&photo_id=12 (API Flickr) |
| 42 | + DELETE http://api.flickr.com/photos/12?api_key=aaabbbccc (une idée d'amélioration) |
| 43 | + |
| 44 | +Très souvent, éviter ce piège revient à créer de nouvelles ressources; |
| 45 | +un exemple avec une API orientée e-commerce: |
| 46 | + |
| 47 | + GET http://example.org/order/144/pay (payer une commande existante) |
| 48 | + |
| 49 | +En fait, créer une ressource "paiement" peut être une bonne idée, ce qui |
| 50 | +permettra de vérifier le status de ce paiement plus tard. |
| 51 | + |
| 52 | + POST http://example.org/payment/?order=144 (création d'un paiement) |
| 53 | + GET http://example.org/payment/23 (renvoie les informations sur le paiement) |
| 54 | + |
| 55 | +Des articles entiers traitent du [design |
| 56 | +d'URLs](http://warpspire.com/posts/url-design/). |
| 57 | + |
| 58 | +## Règle #2: laisser HTTP faire son travail |
| 59 | + |
| 60 | +HTTP a déjà les fonctionnalités, il est omniprésent et déjà testé. |
| 61 | +HTTP, c'est entre autres le content negiciation, le cache de ressources |
| 62 | +et le versioning (via Etags ou Cache-control), des codes d'erreurs |
| 63 | +explicites... pourquoi le réinventer? |
| 64 | + |
| 65 | +Dans le doute, on pourra toujours revoir les [status |
| 66 | +HTTP](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes) et les |
| 67 | +[headers HTTP](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields) |
| 68 | +pour voir si HTTP est déjà équipé pour un besoin particulier. |
| 69 | + |
| 70 | + |
| 71 | +## Règle #3: garder une architecture orientée web |
| 72 | + |
| 73 | +Le web est essentiellement: |
| 74 | + |
| 75 | +* stateless. Oubliez les sessions et la sauvegarde d'état entre |
| 76 | +différentes requêtes. Si vous voulez épargner votre base de données, |
| 77 | +de nombreux systèmes de cache sont adaptés à ce besoin (redis, |
| 78 | +memcached, ehcache...). |
| 79 | +* oriénté ressources. L'important est de ne pas laisser des conventions |
| 80 | + de l'application venir polluer les interactions client/serveur. Cet |
| 81 | +item n'est pas facile à qualifier; mais généralement, une API difficile |
| 82 | +à documenter est un signe. |
| 83 | + |
| 84 | + |
| 85 | +## Règle simple: commencer par comprendre les utilisateurs |
| 86 | + |
| 87 | +Avant de commencer la conception des ressources et des URIs, il faut |
| 88 | +tout d'abord qualifier ses utilisateurs (qui/quoi va utiliser cette |
| 89 | +API?) et quels services nous souhaitons leur rendre. |
| 90 | +Définir quelques priorités sur les items suivants permet de concentrer |
| 91 | +ses efforts sur les aspects importants pour notre API: |
| 92 | + |
| 93 | + |
| 94 | + |
| 95 | +Ce schéma identifie des zones où répartir ses efforts, selon l'API REST |
| 96 | +que l'on souhaite créer. Un exemple avec l'item "usage": si l'API doit |
| 97 | +être intégrée dans des sites tiers, il est préférable de concentrer des |
| 98 | +efforts sur l'utilisation de [JSONP](http://en.wikipedia.org/wiki/JSONP) ou [CORS](http://en.wikipedia.org/wiki/Cross-Origin_Resource_Sharing) afin d'éviter les limitations de sécurité des navigateurs web. |
| 99 | + |
| 100 | +## Un dernier mot |
| 101 | + |
| 102 | +Certains problèmes de conception sont récurrents dans les APIs REST, et |
| 103 | +les opinions sont souvent bien trop tranchées. |
| 104 | + |
| 105 | +### Le versioning revient souvent dans les préoccupations |
| 106 | + |
| 107 | +* pour identifier différentes versions d'une API, l'utilisation d'un |
| 108 | + préfixe est [souvent |
| 109 | +recommandé](http://stackoverflow.com/questions/389169/best-practices-for-api-versioning) |
| 110 | +* lorsque la composition des ressources varie, l'utilisation du |
| 111 | + content-type HTTP personnalisé est la clé (par exemple: `Accept: application/vnd.pullrequest-v2+json`) |
| 112 | +* pour le versioning de ressources (suivre les modifications d'une |
| 113 | + ressource particulière), l'utilisation des Etags (pour le cache) et/ou |
| 114 | +d'un numéro de version dans votre ressource sont suffisants |
| 115 | + |
| 116 | +### Documentation et "découvrabilité" |
| 117 | + |
| 118 | +La documentation est un aspect essentiel d'une API REST. Certains |
| 119 | +prennent le parti d'automatiser et d'outiller un maximum la |
| 120 | +documentation: par exemple, avec [jax-doclets](http://www.lunatech-labs.com/open-source/jax-doclets). |
| 121 | + |
| 122 | +Pour aller plus loin, les APIs peuvent apporter une "découvrabilité": |
| 123 | +permettre au protocole HTTP de documenter l'utilisation de l'API. En |
| 124 | +clair, donner au client REST des indications sur les actions possibles |
| 125 | +via les headers réponse HTTP. Martin Fowler l'explique bien dans un |
| 126 | +article sur le [Richardson Maturity |
| 127 | +Model](http://martinfowler.com/articles/richardsonMaturityModel.html). |
| 128 | + |
| 129 | +### En cas de doute... |
| 130 | + |
| 131 | +Il est souvent utile de se référer à une API REST très |
| 132 | +utilisée et reconnue: l'[API github](http://developer.github.com/) est considérée comme une des |
| 133 | +meilleures à ce jour. |
| 134 | + |
| 135 | +Aussi, je vous recommande la lecture des articles de Steve Klabnik: |
| 136 | + |
| 137 | +* ["nobody understands REST or |
| 138 | + HTTP"](http://blog.steveklabnik.com/2011/07/03/nobody-understands-rest-or-http.html) |
| 139 | +* ["some people understand REST and |
| 140 | + HTTP"](http://blog.steveklabnik.com/2011/08/07/some-people-understand-rest-and-http.html) |
| 141 | + |
| 142 | + |
| 143 | +## Ressources utiles |
| 144 | + |
| 145 | +* Tester son API REST depuis son navigateur avec une [extension Chrome](https://chrome.google.com/webstore/detail/cokgbflfommojglbmbpenpphppikmonn) ou |
| 146 | + avec CURL! |
| 147 | +* Google a beaucoup travaillé sur les aspects RDF/atomPUB avec |
| 148 | + [Gdata](http://code.google.com/intl/fr-FR/apis/gdata/) |
| 149 | +* Le projet Jersey a de [nombreux exemples d'APIs |
| 150 | + REST](http://download.java.net/maven/2/com/sun/jersey/samples/jersey-samples/) |
| 151 | +sur des aspects particuliers, dont |
| 152 | +[Hypermedia](http://download.java.net/maven/2/com/sun/jersey/experimental/hypermedia-action/hypermedia-action-sample/) |
| 153 | +* Mettre en place un ["rate |
| 154 | + limiting"](http://stackoverflow.com/questions/667508/whats-a-good-rate-limiting-algorithm) |
| 155 | +sur son API peut aussi bénéficier d'un cache distribué (memcached, |
| 156 | +redis...) |
| 157 | +* Selon la plate-forme cible, [le format |
| 158 | + JSON](http://jersey.httpjava.net/nonav/documentation/latest/json.html#d4e955) peut être légèrement |
| 159 | + différent. |
| 160 | + |
0 commit comments