grimboite/articles/dev/2019-01-09-build-apis-you-w...

2.8 KiB

Build APIs You Won't Hate

  • Stocker les timezones, pas les offsets. De cette manière, on ne dépend pas des différents calculs de zones, ni des zones pourries comme les îles Chatham qui passent en UTC/GMT+13h45 en été.
  • En règle générale, le verbe PUT est utilisé si on connait l'entièreté de l'URL et que l'action est idempotente (on peut l'exécuter autant de fois qu'on le souhaite, le résultat sera toujours identique).
  • Utilisez des dénominations plurielles. Cela permet par exemple d'envoyer un GET vers l'URL /places/1 ou /places/1,2. Cela permet de conserver une cohérence.
  • Tout doit être une ressource, et chaque ressource doit avoir un contrôleur.
  • On ne passe pas du JSON dans les paramètres d'une URL ! Ca fait moche: checkin[place_id]=1&checkin[message]=This is a bunch of text&checkin[with_friends]=1....

Structure des réponses

Soit on envoie tout dans une structure pluralisée (même s'il n'y a qu'un seul résultat):

{
    "posts": [{
        "id": 1,
        "title": "Zen of Python"
    }]
}

Soit on envoie le résultat concerné par la réponse (un objet ou une liste d'objets) - c'est l'approche minimaliste conseillée par Twitter:

{
    "name": "Hulk Hogan",
    "id": "10002"
}

[
    {
        "name": "Hulk Hogan",
        "id": "10002"
    },
    {
        "name": "Mick Foley",
        "id": "10003"
    }
]

Soit on embarque les collections dans une propriété data (Facebook-style):

{
    "name": "Hulk Hogan",
    "id": "10002"
}

{
    "data": [
        {
            "name": "Hulk Hogan",
            "id": "10002"
        },
        {
            "name": "Mick Foley",
            "id": "10003"
        }
    ]
}

Soit on ajoute par défaut un namespace sur le résultat de retour:

{
    "data": {
        "name": "Hulk Hogan",
        "id": "10002"
    }
}

{
    "data": [
        {
            "name": "Hulk Hogan",
            "id": "10002"
        },
        {
            "name": "Mick Foley",
            "id": "10003"
        }
    ]
}

L'avantage de cette dernière proposition est que chaque résultat est wrappé dans une propriété data (même les sous-propriétés). En gros, on devrait pouvoir faire profiter de pagination, des liens, ... à n'importe quel niveau de l'API.

Voir aussi JSON-API.

Codes de retour

  • 2XX pour les trucs OK
  • 3XX pour les redirections
  • 4XX pour les erreurs côtés clients
  • 5XX pour les erreurs côtés serveur/service.

Tests des points de terminaison

En plus des tests unitaires, on peut envisager du BDD - Behavior Driven Development - notamment avec Cucumber.

Les librairies à garder en mémoire