Design Your API ? Use RAML.
Pour le travail, j'ai dû chercher un moyen de créer une documentation pour une API REST.
Je me suis donc intéressé aux outils existant sur le marché afin de designer simplement et rapidement une API voire même d'avoir une génération de bouchon via la documentation.
Voici les sites les plus intéréssants que j'ai trouvé sur le sujet :
apiary.io
J'ai commencé par apiary.io
Un design sympathique, une documentation simple, gratuit.
Je me suis dit pourquoi pas :)
Ils utilisent un langage crée et défini par leur soin l'API Blueprint.
L'idée est la même pour l'ensemble de ces logiciels : c'est de créer une documentation en ligne, mais aussi un mock afin de tester vos API. (Un mock est un "bouchon").
Voici un exemple de fichier de description pour APIARY :
FORMAT: 1A
HOST: http://www.google.com
# test
Notes API is a *short texts saving* service similar to its physical paper presence on your table.
# Group Notes
Notes related resources of the **Notes API**
## Notes Collection [/notes]
### List all Notes [GET]
+ Response 200 (application/json)
[{
"id": 1, "title": "Jogging in park"
}, {
"id": 2, "title": "Pick-up posters from post-office"
}]
### Create a Note [POST]
+ Request (application/json)
{ "title": "Buy cheese and bread for breakfast." }
+ Response 201 (application/json)
{ "id": 3, "title": "Buy cheese and bread for breakfast." }
## Note [/notes/{id}]
A single Note object with all its details
+ Parameters
+ id (required, number, `1`) ... Numeric `id` of the Note to perform action with. Has example value.
### Retrieve a Note [GET]
+ Response 200 (application/json)
+ Header
X-My-Header: The Value
+ Body
{ "id": 2, "title": "Pick-up posters from post-office" }
Voici le rendu de la documentation :
Cependant, j'ai eu quelques limitations dans ma description d'API. C'est seulement pour des cas particuliers, mais bloquants dans mon cas (validation, documentation sur les erreurs et sur les parameters autres que require ou texte ...)
RAML API Design
Je suis donc parti à la recherche d'un autre format de description d'API. Je suis donc tombé sur le RAML.
C'est un format intéressant, car il semble plus abouti que les autres formats. Il permet de définir des schemas de validation (xml ou JSON), plusieurs réponses, avoir une documentation HTML ou markdown ...
Le format n'est pas beaucoup différent de l'API Blueprint.
Il s'agit en fait de YAML avec une structure particulière.
La description de l'API est ici : https://github.com/raml-org/raml-spec
Elle est bien écrite et complète, ce qui est agréable.
J'ai utilisé la validation par schéma pour mes réponses JSON.
Je vous propose donc de jeter un oeil au lien suivant, permettant de valider votre json et votre schema facilement : http://jsonschemalint.com/
Voici un fichier d'exemple :
#%RAML 0.8
title: Mon API
baseUri: http://mocksvc.mulesoft.com/mocks/1.../{version}
version: v1
/test:
/:
post:
body:
application/json:
schema: |
{
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
}
example: |
{
["12315412131" ,"12315412145"]
}
description: |
test produits
<table>
<tr>
<td>Parametre</td>
<td>exemple</td>
<td>description</td>
<td>obligatoire</td>
<td>format</td>
</tr>
<tr>
<td>id</td>
<td>"12315412131"</td>
<td>id</td>
<td>true</td>
<td>string</td>
</tr>
</table>
responses:
200:
description: |
Retourne un tableau JSON de produit
body:
application/json:
schema: |
{
"type": "array",
"items": {
"type": "object",
"description" : "test",
"properties": {
"reference": {
"description" : "id produit",
"type": "string",
"required":true
},
"nombre": {
"description" : "nombre",
"type": "integer",
"required":true
}
}
}
}
example: |
{
[
{ reference: '1234567890123', nombre: 134 },
{ reference: '1234567890125', nombre: 20 },
{ reference: '1234567890127', nombre: 0 },
]
}
400:
description: |
Erreur retourne par le serveur
* CODE 101 : Format
body:
application/json:
schema: |
{
"ERREUR": {
"description" : "Si un erreur est presente",
"type": "object",
"properties": {
"CODE" : {
"type": "integer"
},
"MSG" : {
"type": "string"
}
}
}
}
example: |
{
ERREUR : { CODE: 101, MSG: 'Format Inconnu' }
}
500:
description: |
Erreur retourne par le serveur
* CODE 102 : Inconnu
* CODE 103 : Existant, mais erreur
body:
application/json:
schema: |
{
"type": "array",
"items": {
"type": "object",
"description" : "tsdgfsdf qsf sd ",
"properties": {
"reference": {
"description" : "sdfgsdfg dfsg df g",
"type": "string",
"required":true
},
"nombre": {
"description" : "sdfg dfs gsdf g",
"type": "integer"
},
"ERREUR": {
"description" : "sdfgd gfsdfg sdfg",
"type": "object",
"properties": {
"CODE" : {
"type": "integer"
},
"MSG" : {
"type": "string"
}
}
}
}
}
}
example: |
{
[
{ reference: '1234567890123', nombre: 134 },
{ reference: '1234567890124', ERREUR: { CODE: 102, MSG: 'Inconnu' } }
]
}
La documentation générée est sympathique aussi. Cependant avec le JS présent, il est impossible d'imprimer le document ou de sortir un PDF. C'est là le plus gros défaut que j'ai trouvé actuellement à cette méthode.
Je pense d'ailleurs développer une script Python afin de générer une documentation HTML en Standalone et surtout imprimable en PDF.
Je vais faire un autre article afin de décrire plus en détail l'utilisation du RAML.
Conclusion
Si votre client est d'accord pour avoir une documentation d'API en ligne non imprimable, je vous conseille le RAML. Excellent format assez rapide à écrire après avoir pris le coup de main. Le mock fonctionne bien, même s'il est dommage qu'il retourne toujours le 200 si la réponse est bien formée.
PS: Si vous cherchez un bon livre sur les API REST, je vous conseille celui-ci : O'REILLY RESTful Web APIs