Interfaces de programmation (API)

Quelques raccourcis :

Ce qui suit vise à regrouper diverses réflexions et considérations quant au développement d'une interface de programmation (Application Programming Interface, API), incluant le choix des noms, des signatures de fonctions, les modalités d'appel, la documentation, la gestion des erreurs, etc.

Notez au passage que toutes ces considérations sont traitées individuellement sur d'autres pages de ce site; ce que j'ai essayé de grouper ici tient à l'art (il serait présomptueux de parler d'Art ou de science ici) du design d'outils logiciels qui serviront à des multitudes, et qui constitueront un point d'entrée pour une gamme de services ou de fonctionnalités.

Je dois avouer que le sujet m'intéresse beaucoup, mais que le temps me manque, ce qui explique que vous trouverez ici surtout des réflexions de tiers (un jour, j'ajouterai les miennes). De même, l'organisation par section de cette page est embryonnaire, mais je ferai mieux (éventuellement) quand j'en aurai le temps.

Si vous avez des questions d'ordre plus général sur la pratique de la programmation, voir Pratique-programmation.html

Il y a de plus en plus d'API de type REST. À propos de ces API, voir : ../Web/Developpement-Web.html#api_rest

Source

Généralités

Considérations d'ordre général sur le design d'une API.

Technique

À propos des aspects plus techniques du design d'API et de Framework :

L'influence des langages impliqués

Réflexions de Raymond Chen :

Qualité

Pour une présentation d'une API de grande qualité, je vous suggère de jeter un coup d'oeil à ce que propose Howard Hinnant dans https://www.youtube.com/watch?v=tzyGjOm8AKo pour manipuler des dates. Portez attention à ses choix de design

Qu'est-ce qui fait qu'une API soit bonne ou excellente?

Dans une excellente présentation de 2014 (https://www.youtube.com/watch?v=zgOF4NrQllo pour la présentation, http://meetingcpp.com/tl_files/2013/talks/Keynote-cxx11-library-design-ericniebler.pdf pour les diapositives électroniques), Eric Niebler offre quelques recommandations quant au design d'une API en C++ depuis C++ 11. En résumé :

Il met de l'avant un tableau comparatif entre les pratiques recommandées avec C++ 03 et C++ 11 :

Catégorie Avec C++ 03 Avec C++ 11
Petit intrant

Passage par valeur

Passage par valeur

Sink

s/o

Passage par valeur

Gros intrant

Passage ref-vers-const

Passage ref-vers-const

Petit extrant

Retourner par copie

Retourner par copie

Gros extrant

Passage par référence non-const

Retourner par copie (pertmettre le mouvement et le Copy Elision)

Intrant et extrant

Passage par référence non-const

Passage par référence non-const ou repenser l'interface avec des objets représentant des algorithmes

Comme il le rappelle, dans le cas des intrants, certains sont voués à être utilisés en lecture seule (Read-Only), alors que d'autres sont ce qu'on nomme des Sinks, et sont consommés par la fonction appelée :

template <class T>
    void f(const T&); // lecture seule
 template <class T>
    void f(T&&); // Sink
template <class T, class U>
    void f(const T&, const U&); // lecture seule, lecture seule
template <class T, class U>
    void f(const T&, U&&); // lecture seule, Sink
template <class T, class U>
    void f(T&&, const U&); // sink, lecture seule
 template <class T, class U>
    void f(T&&, U&&); // Sink, Sink

Pour ce qui est des objets représentant des algorithmes, Niebler met de l'avant que dans bien des cas, la raison pour laquelle nous avons recours à des paramètres d'entrée/ sortie est que notre algorithme est Stateful, et que cette caractéristique mériterait d'être explicitée par un objet encapsulant ce concept.

Il propose de réécrire getline(), qui « compose mal » avec d'autres fonctions (elle retourne une référence sur le flux duquel la lecture a été faite, pas la ligne lue!) par un getlines() (pluriel) qui encapsulerait les opérations plus primitives de lecture de lignes et réutiliserait l'espace alloué pour la chaîne dans laquelle la première lecture est faite pour que les lectures subséquentes soient plus rapides.

Pour le design des types :

Eric Niebler propose le trait suivant pour tester si un type T est régulier :

template <typename T>
   struct is_regular
      : std::integral_constant<
           bool, std::is_default_constructible<T>::value &&
                 std::is_copy_constructible<T>::value &&
                 std::is_move_constructible<T>::value &&
                 std::is_copy_assignable<T>::value &&
                 std::is_move_assignable<T>::value &&
        >
{
};

Ce trait omet les opérateurs ==, != et < qui sont typiquement associés aux types réguliers, alors il est sans doute perfectible.

Pour ce qui est des modules :

Saines pratiques

Quelques guides de saines pratiques et quelques groupes de conseils pour vous guider dans le design de vos API :

Pratiques malsaines

Certains ont exprimé leur point de vue par la négative, et nous offrent leur conception de ce qu'il vaut mieux ne pas faire lors du développement d'une API.

Critiques d'API existantes

Les saines pratiques de conception d'une bibliothèque, d'une API ou d'un Framework sont un créneau important des saines pratiques de programmation en général. Plusieurs ont publié leur vision ou leurs expériences à se sujet.

À propos de l'API de Facebook :

À propos de l'API de Dropbox :

À propos du design d'OpenCV :

À propos de l'API de Twitter :

API de mauvaise qualité :


Valid XHTML 1.0 Transitional

CSS Valide !