lundi 5 décembre 2011

Le design des web api

Une web api est essentiellement une porte, un point d'accès à un traitement ou une ressource distante. Tout le challenge du design d'api se résume à faciliter au maximum l'accès à ce qui se trouve derrière la porte d'entrée.

Une api va raccorder une application au reste du monde, à autre chose que ses utilisateurs humains et permettre son intégration dans des contextes variés comme l'import et l'export de données, l'automatisation d'un grand nombre de traitements et bien d'autres choses encore.
Des développeurs tiers vont pouvoir créer de nouvelles solutions en agrégeant les fonctionnalités exposées par vos api avec celles d'autres fournisseurs. Bien souvent cela générera des usages que les créateurs d'origine n'avaient pas imaginé.

Pour les concepteurs en charge d'un  projet api, le produit final doit être l'api elle-même. Cette dernière n'est pas un objet de deuxième zone raccordé tant bien que mal à l'application principale. Les utilisateurs ne sont plus ceux de l'application mais les intégrateurs ou les développeurs qui vont l'utiliser dans leurs programmes.

Elle doit donc être pensée pour faciliter l'activité de ce type particulier d'utilisateurs et non pas seulement pour résoudre une problématique technique ou métier. L'api est malheureusement souvent un élément rajouté, qui n'a pas été forcément prévu dès le départ.

Pourquoi web api ?
On parle de web api parce que les traitements et les données sont accessibles à travers des urls http (même principe que pour les sites web, par exemple : https://api.faascape.com/mail/messages). Les principes techniques qui ont fait le succès du web sont utilisés exactement comme pour la consultation d'un site avec un navigateur à ceci près qu'au lieu de retourner des données visualisables par un utilisateur humain, l'url pointe vers des données destinées à être utilisées par un programme informatique.

Il y a quelques règles simples à garder en tête pour fournir à vos utilisateurs une api de bonne qualité.

Simplicité d'utilisation.
Une bonne api doit être simple d'utilisation, sa mise en oeuvre doit être rapide et intuitive. On peut mesurer une partie de cette simplicité par le nombre de lignes de code nécessaires pour utiliser une fonctionnalité ou par le temps mis à l'intégrer.

La rapidité de prise en main est, entre autres choses, lié au nombre de nouveaux concepts que doit maîtriser un nouvel utilisateur. Il est donc peu recommandé de mettre en oeuvre des mécanismes exotiques qui seraient propres uniquement à votre seule implémentation.

Etre basé sur des standards est un avantage. Selon le site ProgrammableWeb, la technologie la plus utilisée pour exposer une web api est REST et le format de données le plus populaire est JSON.

Le nombre d'éléments à utiliser pour effectuer une action doit être limité en terme de nombre de paramètres et de structure des urls. En faisant cela, on limite les risques d'erreur et de mauvaise utilisation.

Exemple
Imaginons un site de vente de voitures d'occasion qui souhaite mettre à disposition sa base de données via une api.

Compliqué : http://api.monsite.com/v1.314/fr/recherche?type-vehicule=tourisme&annee=1996&couleur=rouge& .......

Simple : http://api.monsite.com/vehicule/tourisme/1996?couleur=rouge& ....

On peut néanmoins envisager plusieurs niveaux d'utilisation : un niveau simple permettant de très rapidement mettre en oeuvre les premières fonctionnalités, puis éventuellement un mode "avancé" autorisant un paramétrage plus détaillé.

La démarche est exactement la même que pour une interface visuelle, moins de fonctionnalités accessibles directement pour ne pas perdre l'utilisateur dans un méandre d'options peu compréhensibles, mais toute la puissance du logiciel est disponible en activant les options "expert".

Aspects métier / aspects techniques
La vue "métier" présentée par l'api doit être lié au monde réel. Le vocabulaire utilisé pour exprimer telle ou telle fonction ou ressource doit se rapporter à la vrai dénomination du métier pas à un mot en relation avec  la technique d'implémentation. Même si le produit s'adresse à des développeurs, il ne faut dénaturer les traitements sous-jacents  en les affublant de noms uniquement techniques.

Dans notre exemple précédent ajouter la version (v1.314) et la langue des critères (fr) revient à mélanger des informations techniques avec des informations métiers. Il y a d'autres moyens de transmettre des informations dans les requêtes sans "polluer" les urls.

Performance
La perception d'efficacité est lié au temps nécessaire pour un obtenir un résultat.
N'oublions pas que la web-api va nécessiter des allers-retours sur Internet pour récupérer des données. Il est très important de prévoir systématiquement un mode 'traitement de masse' pour pouvoir à partir d'une seule requête effectuer plusieurs traitements, ajout de données, modification ou suppression.
En faisant cela, un seul appel au service distant permettra d'effectuer plus de traitements ou d'obtenir plus de résultats en moins de temps.

Exemple
Pour ajouter un nouveau véhicule à notre base de données de voiture, nous envisageons d'utiliser une requête POST avec un descriptif du véhicule à ajouter sur l'url http://api.monsite.com/vehicule

POST http://api.monsite.com/vehicule
{
"marque":"aston martin",
"modele": "v12 vantage",
"annee":"1993",
"couleur":"gris"
}

On peut sans effort envisager une variante pour créer plusieurs véhicules avec une seule requête :


POST http://api.monsite.com/vehicule
[
   {
   "marque":"aston martin",
   "modele": "v12 vantage",
   "annee":"1993",
   "couleur":"gris"
   },

   {
   "marque":"renault",
   "modele": "clio",
   "annee":"1998",
   "couleur":"rouge"
   }
]



Dans la définition de l'api, un juste équilibre doit être trouvé entre la possibilité de récupérer le maximum de données avec le moins d'appels possible ou, au contraire, transférer uniquement les données utiles et minimiser le volume d'information à télécharger.
Un ou deux paramètres peuvent servir à décrire le détail des informations à récupérer pour chaque url cible et ainsi permettre un ajustement du volume de données transféré en fonction des besoins réels.
Typiquement pour une requête de sélection, on permettra de spécifier facultativement le nombre de résultats à transmettre et à partir de quel rang on souhaite récupérer les données. Sans option, la requête retourne tous les résultats. C'est l'utilisateur de l'api qui est en contrôle.

Robustesse
Au delà du fait d'avoir pris toutes les dispositions pour avoir une api constamment opérationnelle, avec des temps de réponses raisonnables, géré les questions de montée en charge lié au succès, la perception de robustesse est également lié à un comportement prévisible. Par exemple, il faut éviter, en cas de problème, de remonter des messages d'erreurs ésotériques liés à l'implémentation interne. "Erreur d'accès
aux données" fait moins peur que "4565XDH : corrupted index". Ce qui se passe derrière l'api est hors de portée de l'utilisateur, il ne peut pas agir dessus, inutile donc de l'ensevelir sous des détails techniques qu'il ne pourra pas exploiter. Par contre, votre gestion de log devra bien entendu enregistrer toutes ces informations ainsi que ce qui permettra de rejouer éventuellement la requête ayant entraîné l'apparition du problème.

Dans le même ordre d'idée, toutes les données transmises à la web api doivent être soigneusement vérifiées avant d'être utilisées. Si une incohérence est détectée, un message d'erreur décrivant précisément la nature de l'erreur doit être retourné (pour le développeur) accompagné d'un code d'erreur significatif (pour l'application) indiquant que le traitement demandé n'a pu être effectué.

L'interface utilisateur de la web api : la documentation
Claire, synthétique, la documentation d'une web api se doit absolument d'être accessible en ligne, la mise à jour de la documentation doit être en permanence synchronisée à celle du code.
Il est fondamental d'accompagner le descriptif de chaque fonctionnalité d'exemples de code dans plusieurs langages, utilisables par simple copier / coller.
Cette documentation peut être lié à un système de discussion permettant aux utilisateurs de faire remonter leurs remarques et leurs questions directement. Les réponses apportées seront un bon complément à la documentation de base.
A titre d'exemple, voici un excellent outil en ligne qui vous permettra d'obtenir des documentations dignes de ce nom pour vos api : http://turnapi.com/

http://www.faascape.com
http://twitter.com/faascapefr

6 commentaires:

  1. Merci pour cette excellente introduction au design d'une web API.
    En complément du passage sur le nombre de résultats à transmettre, je trouve intéressante l'approche de Google avec son API DoubleClick for Publishers (DFP) qui limite le nombre maximum de résultats retournés à 500 pour des raisons de performance (j'imagine).
    Ce qui oblige le développeur à intégrer une sélection intelligente des résultats demandés à l'API, en multipliant les critères de recherche ou en instaurant une pagination des résultats.
    Ce qui est indispensable dans le cas d'une API susceptible de retourner un très grand nombre de résultats.
    http://code.google.com/intl/fr/apis/dfp/docs/developers_guide.html

    RépondreSupprimer
  2. Tout à fait d'accord.
    D'une manière générale, il va falloir s'habituer à traiter des volumes de données de plus en plus importants en temps réel (ou presque) et à distance. La sélection pertinente des données à traiter est donc effectivement une question importante.

    RépondreSupprimer
  3. Puisque l'on parle de standard et de sélection pertinente, je tenais à mentionner opensearch.org dont le but est de fournir un format uniforme pour décrire l'API d'un moteur de recherche.

    Un point que je trouve également important lors de la création d'une API est la création d'un client minimal, open source, dans un langage populaire (java/c#/python...). Cela permet à l'utilisateur de prendre plus rapidement en main l'API. Et cela montre également que l'éditeur pense un peu à ces futures consommateurs et ne sort pas une API juste par ce que c'est la nouvelle tendance.

    RépondreSupprimer
  4. @Bertrand, merci pour ce commentaire et pour la référence à opensearch.org (que je ne connaissais pas du tout).

    Pour ce qui est du client, je préfère proposer plusieurs exemples dans différents langages (comme tu le suggères) pour encourager les usages et bien décrire les modes de fonctionnement mais rester plutôt dans des technologies "neutres" (REST) sans interface spécifique.

    Cela permet :
    - de rester ouvert sur tous les langages sans privilégier les uns par rapport aux autres,
    - d'aller plus vite car il n'y a pas de multiples technologies à gérer
    - d'éviter les problèmes de maintenance à plus long terme

    RépondreSupprimer
  5. Article intéressant. Il faut néanmoins noter que le REST n'est pas une technologie - comme le serait le SOAP - mais une "théorie", une façon d'organiser les données (ressources).

    RépondreSupprimer
  6. Pour simplifier l'écriture de clients d'API REST, SPORE est une bonne solution.
    SPORE est la spécification d'un langage de description d'une API REST, indépendant du langage de programmation.
    Plusieurs implémentations permettent d'utiliser cette description dans votre langage de programmation favori pour interagir très facilement en tant que client de l'API.
    https://github.com/SPORE/specifications

    RépondreSupprimer