
La plupart des tâches effectuées par les ingénieurs logiciels modernes impliquent des API : des interfaces publiques permettant de communiquer avec un programme, comme celle-ci de Twilio. J'ai passé beaucoup de temps à travailler avec des API, tant à les créer qu'à les utiliser. J'ai écrit des API publiques pour des développeurs tiers, des API privées à usage interne (ou destinées à une seule page frontale), des API REST et GraphQL, et même des interfaces non réseau comme celles destinées aux outils en ligne de commande.
Tout comme pour la conception de bons systèmes logiciels, je pense que la plupart des conseils qui circulent sur la conception d'API sont trop sophistiqués. Les gens se perdent dans des discussions sur ce qu'est le « vrai » REST, ou si HATEOAS est une bonne idée, etc. Cet article est ma tentative de mettre par écrit tout ce que je sais sur la conception de bonnes API.
La conception d'API est un équilibre entre familiarité et flexibilité
Si cela est vrai pour les systèmes, et ça l'est, cela l'est encore plus pour les API : les bonnes API sont ennuyeuses. Une API intéressante est une mauvaise API (ou du moins, elle serait meilleure si elle était moins intéressante). Pour les développeurs qui les créent, les API sont des produits complexes qu'ils passent du temps à concevoir et à perfectionner. Mais pour les développeurs qui les utilisent, les API sont des outils qui leur permettent d'atteindre un autre objectif. Tout le temps qu'ils passent à réfléchir à l'API plutôt qu'à cet objectif est du temps perdu. De leur point de vue, une API idéale devrait être si familière qu'ils sauraient plus ou moins comment l'utiliser avant même d'avoir lu la documentation.
Cependant, une grande différence par rapport à la plupart des systèmes logiciels est que les API sont difficiles à modifier. Une fois que vous publiez une API et que les gens commencent à l'utiliser, toute modification de l'interface rendra le logiciel de vos utilisateurs inutilisable. Bien sûr, il est possible d'apporter des modifications. Mais (comme je le dirai plus loin) chaque modification a un coût important : chaque fois que vous obligez vos utilisateurs à mettre à jour leur logiciel, ils envisagent sérieusement d'utiliser une autre API plus stable. Cela incite fortement les créateurs d'API à concevoir soigneusement leur produit et à le faire correctement dès le départ.
Cette tension crée une dynamique intéressante pour les ingénieurs qui développent des API. D'un côté, ils veulent créer l'API la plus simple possible. De l'autre, ils veulent faire preuve d'ingéniosité pour conserver une flexibilité à long terme. En gros, la conception d'une API consiste à trouver un équilibre entre ces deux objectifs incompatibles.
NOUS NE PERTURBONS PAS L'ESPACE UTILISATEUR
Que se passe-t-il lorsque vous devez apporter des modifications à votre API ? Les modifications additives, par exemple l'ajout d'un nouveau champ dans la réponse, ne posent généralement pas de problème. Certains consommateurs peuvent paniquer s'ils obtiennent plus de champs que prévu, mais à mon avis, cela est irresponsable. Vous devez vous attendre à ce que les consommateurs d'API ignorent les champs inattendus (les langages de type JSON sensibles le font par défaut).
Cependant, vous ne pouvez pas supprimer ou modifier les types de champs. Vous ne pouvez pas modifier la structure des champs existants (par exemple, déplacer [c]user.address[/] vers user.details.address dans la réponse JSON). Si vous le faites, chaque élément de code qui dépend de ces champs sera immédiatement interrompu. Les consommateurs de ce code le signaleront comme un bug, et les responsables de la maintenance du code seront (lorsqu'ils s'en rendront compte) à juste titre furieux que vous ayez délibérément endommagé leur logiciel.
Le principe ici est similaire au célèbre slogan de Linus Torvalds : « WE DO NOT BREAK USERSPACE » (Nous ne cassons pas l'espace utilisateur). En tant que responsable d'une API, vous avez en quelque sorte le devoir sacré d'éviter de nuire à vos utilisateurs en aval. Cette norme est très stricte, car de nombreux logiciels dépendent d'un grand nombre d'API (qui dépendent elles-mêmes d'API en amont, et ainsi de suite). Un responsable d'API imprudent suffisamment en amont peut endommager des centaines, voire des milliers de logiciels en aval.
Vous ne devez jamais modifier une API simplement parce qu'elle serait plus propre ou parce qu'elle est un peu maladroite. L'en-tête « referer » dans la spécification HTTP est connu pour être une faute d'orthographe du mot « referrer », mais il n'a pas été modifié, car nous ne cassons pas l'espace utilisateur.
Modifier les API sans perturber l'espace utilisateur
Il est honnêtement difficile de trouver des exemples où une API nécessite vraiment une modification radicale. Mais parfois, la valeur technique d'une modification est suffisamment élevée pour que vous décidiez de prendre votre courage à deux mains et de la faire quand même. Dans ces cas-là, comment modifier votre API de manière responsable ? La réponse est la gestion des versions.
La gestion des versions d'API signifie « servir à la fois l'ancienne et la nouvelle version de votre API ». Les consommateurs existants peuvent continuer à utiliser l'ancienne version, tandis que les nouveaux consommateurs peuvent opter pour la nouvelle. La façon la plus simple de procéder est d'inclure quelque chose comme /v1/ dans l'URL de votre API. L'API de chat d'OpenAI se trouve à l'adresse v1/chat/completions. Ainsi, si jamais ils souhaitent remanier totalement la structure, ils peuvent le faire dans v2/chat/completions tout en permettant aux consommateurs existants de continuer à fonctionner.
Une fois que les anciennes et nouvelles versions fonctionnent simultanément, vous pouvez commencer à demander aux utilisateurs de passer à la nouvelle version. Cela prend beaucoup de temps : des mois, voire des années. Même avec des bannières sur le site web, des documents, des e-mails personnalisés et des en-têtes dans les réponses API, lorsque vous supprimerez enfin l'ancienne version, vous aurez encore beaucoup d'utilisateurs mécontents que vous ayez rendu leur logiciel inutilisable. Mais au moins, vous aurez fait tout ce que vous pouviez.
Il existe de nombreuses autres façons de gérer les versions d'API. L'API Stripe gère les versions dans un en-tête et permet aux comptes de définir leur version par défaut dans l'interface utilisateur. Mais le principe est le même : tous les utilisateurs de l'API Stripe peuvent être sûrs que Stripe ne décidera pas de rendre leurs applications inutilisables, et ils peuvent mettre à niveau les versions à leur propre rythme.
Je n'aime pas la gestion des versions d'API. Je pense qu'au mieux, c'est un mal nécessaire, mais cela reste un mal. Cela prête à confusion pour les utilisateurs, qui ne peuvent pas facilement rechercher la documentation de votre API sans s'assurer que le sélecteur de version correspond à la version qu'ils utilisent. Et c'est un cauchemar pour les responsables de la maintenance. Si vous avez trente points de terminaison API, chaque nouvelle version que vous ajoutez introduit trente nouveaux points de terminaison à maintenir. Vous vous retrouverez rapidement avec des centaines d'API qui devront toutes être testées, déboguées et faire l'objet d'un support client.
Bien sûr, l'ajout d'une nouvelle version ne double pas la taille de votre base de code. Tout backend de gestion des versions d'API sensé disposera d'une couche de traduction capable de convertir une réponse en n'importe laquelle de vos versions d'API publiques. Stripe dispose d'un système similaire : la logique métier réelle est la même pour toutes les versions, de sorte que seuls la sérialisation et la désérialisation des paramètres doivent tenir compte de la gestion des versions. Cependant, ce type d'abstraction présente toujours des failles. Voir ce commentaire HN de 2017 d'un employé de Stripe, soulignant que certaines modifications de versionnement nécessitent une logique conditionnelle dans tout le « code central ».
En bref, vous ne devriez utiliser le versionnement des API qu'en dernier recours.
Le succès de votre API dépend entièrement du produit
Une API en soi ne fait rien. C'est une couche entre l'utilisateur et ce qu'il veut réellement. Pour l'API OpenAI, il s'agit de la capacité à faire des inférences avec un modèle linguistique. Pour l'API Twilio, il s'agit d'envoyer des SMS. Personne n'utilise une API parce que celle-ci est élégamment conçue. Les utilisateurs l'utilisent pour interagir avec votre produit. Si votre produit est suffisamment intéressant, les utilisateurs afflueront même vers une API médiocre.
C'est pourquoi certaines des API les plus populaires sont un cauchemar à utiliser. Facebook et Jira sont connus pour avoir des API épouvantables, mais cela n'a pas d'importance : si vous souhaitez vous intégrer à Facebook ou Jira, ce que vous faites, vous devez passer du temps à les comprendre. Bien sûr, ce serait bien si ces entreprises avaient une meilleure API. Mais pourquoi investir du temps et de l'argent pour l'améliorer alors que les gens vont de toute façon s'y intégrer ? Écrire de bonnes API est vraiment difficile.
Je vais donner de nombreux conseils concrets dans la suite de cet article sur la manière d'écrire de bonnes API. Mais il est important de se rappeler que la plupart du temps, cela n'a pas d'importance. Si votre produit est attractif, n'importe quelle API à peine fonctionnelle fera l'affaire ; s'il ne l'est pas, peu importe la qualité de votre API. La qualité de l'API est une caractéristique marginale : elle n'a d'importance que lorsqu'un consommateur doit choisir entre deux produits fondamentalement équivalents.
Soit dit en passant, la présence d'une API est une tout autre histoire. Si un produit ne dispose d'aucune API, cela pose un gros problème. Les utilisateurs techniques exigeront un moyen d'intégrer le logiciel qu'ils achètent via du code.
Les produits mal conçus ont généralement de mauvaises API
Une API techniquement excellente ne peut pas sauver un produit que personne ne veut utiliser. Cependant, un produit techniquement médiocre peut rendre presque impossible la création d'une API élégante. En effet, la conception d'une API suit généralement les « ressources de base » d'un produit (par exemple, les ressources de Jira seraient les problèmes, les projets, les utilisateurs, etc. ). Lorsque ces ressources sont mal configurées, l'API l'est également.
Prenons l'exemple d'un système de blog qui stocke les commentaires en mémoire sous forme de liste liée (chaque commentaire comporte un champ « next » qui pointe vers le commentaire suivant dans le fil). C'est une très mauvaise façon de stocker les commentaires. La manière la plus naïve d'intégrer une API REST à ce système serait d'avoir une interface qui ressemble à ceci :
GET /comments/1 -> { id: 1, body: « ... », next_comment_id: 2 }Ou pire encore, comme ceci :
GET /comments -> {body: « ... », next_comment: { body: « ... », next_comment: {...}}}Cet exemple peut sembler ridicule, car en pratique, il suffirait d'itérer sur la liste liée et de renvoyer un tableau de commentaires dans la réponse de l'API. Mais même si vous êtes prêt à faire ce travail supplémentaire, jusqu'où allez-vous itérer ? Dans un fil de discussion contenant des milliers de commentaires, est-il impossible de récupérer les commentaires après les quelques centaines premiers ? Votre API de récupération des commentaires devra-t-elle utiliser une tâche en arrière-plan, obligeant l'interface à se transformer en quelque chose comme :
POST /comments/fetch_job/1 -> { job_id: 589 } GET /comments_job/589 -> { status: “complete”, comments: [...] }C'est ainsi que certaines des pires API voient le jour. Les contraintes techniques qui peuvent être habilement dissimulées dans l'interface utilisateur sont mises à nu dans l'API, obligeant les consommateurs d'API à comprendre bien plus que nécessaire la conception du système.
Authentification
Vous devez permettre aux utilisateurs d'utiliser vos API avec une clé API à longue durée de vie. Oui, les clés API ne sont pas aussi sécurisées que diverses formes d'identifiants à courte durée de vie, comme OAuth (que vous devriez probablement également prendre en charge). Cela n'a pas d'importance. Chaque intégration avec votre API commence par un simple script, et l'utilisation d'une clé API est le moyen le plus simple de faire fonctionner un script simple. Vous voulez faciliter au maximum la tâche des ingénieurs qui souhaitent se lancer.
Bien que les utilisateurs d'une API écrivent (presque par définition) du code, beaucoup d'entre eux ne sont pas des ingénieurs professionnels. Il peut s'agir de commerciaux, de chefs de produit, d'étudiants, d'amateurs, etc. Lorsque vous êtes ingénieur dans une entreprise technologique et que vous développez une API, il est facile d'imaginer que vous la développez pour d'autres personnes comme vous : des ingénieurs logiciels professionnels compétents à temps plein. Mais ce n'est pas le cas. Vous la développez pour un large éventail de personnes, dont beaucoup ne sont pas à l'aise avec l'écriture ou la lecture de code. Si votre API exige des utilisateurs qu'ils effectuent des tâches difficiles, comme une négociation OAuth, beaucoup d'entre eux auront des difficultés.
Idempotence et nouvelles tentatives
Lorsqu'une requête API aboutit, vous savez qu'elle a fait ce qu'elle devait faire. Mais qu'en est-il lorsqu'elle échoue ? Certains types d'échecs vous indiquent ce qui s'est passé : un 422 signifie généralement qu'elle a échoué pendant la phase de validation de la requête, avant qu'aucune action n'ait été entreprise. Mais qu'en est-il d'un 500 ? Et d'un délai d'expiration ?
C'est important pour les opérations API qui entraînent une action. Si vous utilisez une API Jira pour créer un commentaire sur un ticket et que la requête renvoie une erreur 500 ou expire, devez-vous réessayer ? Vous ne savez pas avec certitude si le commentaire a été créé ou non, car l'erreur peut survenir après cette opération. Si vous réessayez, vous risquez de publier deux commentaires. C'est encore plus important lorsque l'enjeu dépasse un simple commentaire Jira. Que se passe-t-il si vous transférez une certaine somme d'argent ? Que se passe-t-il si vous distribuez des médicaments ?
La solution est l'idempotence, un terme sophistiqué qui signifie « la requête doit pouvoir être réessayée en toute sécurité sans créer de doublons ». La méthode standard pour y parvenir consiste à prendre en charge une « clé d'idempotence » dans la requête (par exemple, une chaîne définie par l'utilisateur dans un paramètre ou un en-tête). Lorsque le serveur API reçoit une requête « créer un commentaire » avec une clé d'idempotence, il vérifie d'abord s'il a déjà vu cette clé d'idempotence. Si c'est le cas, il ne fait rien ; sinon, il crée le commentaire, puis enregistre la clé d'idempotence. De cette façon, vous pouvez envoyer autant de nouvelles tentatives que vous le souhaitez, à condition qu'elles aient toutes la même clé d'idempotence : l'opération ne sera effectuée qu'une seule fois.
Comment stocker la clé ? J'ai vu des gens la stocker de manière durable et spécifique à une ressource (par exemple, dans une colonne du tableau des commentaires), mais je ne pense pas que cela soit strictement nécessaire. Le plus simple est de la placer dans Redis ou dans un magasin clé/valeur similaire (avec la clé d'idempotence comme clé). Les UUID sont suffisamment uniques pour que vous n'ayez pas besoin de les limiter à un utilisateur, mais vous pouvez tout aussi bien le faire. Si vous ne traitez pas de paiements, vous pouvez même les faire expirer après quelques heures, car la plupart des nouvelles tentatives ont lieu immédiatement.
Avez-vous besoin de clés d'idempotence pour chaque requête ? Eh bien, vous n'en avez pas besoin pour les requêtes de lecture, car les doubles lectures sont inoffensives. Vous n'en avez généralement pas besoin non plus pour les requêtes de suppression, car si vous supprimez par ID de ressource, cet ID sert de clé d'idempotence. Réfléchissez-y : si vous envoyez trois requêtes DELETE comments/32 à la suite, cela ne supprimera pas trois commentaires. La première requête réussie supprimera le commentaire avec l'ID 32, et les requêtes restantes renverront une erreur 404 lorsqu'elles ne trouveront pas le commentaire déjà supprimé.
Dans la plupart des cas, l'idempotence doit être facultative. Comme je l'ai dit plus haut, vous devez vous assurer que votre API est accessible aux non-ingénieurs (qui trouvent souvent l'idempotence difficile à comprendre). Dans l'ensemble, il est plus important d'attirer davantage de personnes vers votre API que de supprimer les commentaires dupliqués occasionnels des utilisateurs qui n'ont pas lu la documentation.
Sécurité et limitation du débit
Les utilisateurs qui interagissent avec votre interface utilisateur sont limités par la vitesse de leurs mains. Si certains flux sont coûteux à traiter pour votre backend, un utilisateur malveillant ou négligent ne peut déclencher ces flux qu'à la vitesse à laquelle il peut cliquer dessus. Les API sont différentes. Toute opération que vous exposez via une API peut être appelée à la vitesse du code.
Soyez prudent avec les API qui effectuent beaucoup de tâches en une seule requête. Lorsque je travaillais chez Zendesk, nous avions une API qui permettait d'envoyer des notifications à tous les utilisateurs d'une application particulière. Certains développeurs tiers entreprenants l'ont utilisée pour créer un système de chat intégré à l'application, dans lequel chaque message envoyait une notification à tous les autres utilisateurs du compte. Pour les comptes comptant plus d'une poignée d'utilisateurs actifs, cela a systématiquement planté le serveur backend des applications.
Nous n'avions pas prévu que des personnes créeraient une application de chat à partir de cette API. Mais une fois qu'elle a été mise en place, les gens en ont fait ce qu'ils voulaient. J'ai participé à de très nombreux appels d'urgence dont la cause principale était une intégration client artisanale qui effectuait des tâches absurdes, telles que :
- Créer et supprimer les mêmes enregistrements des centaines de fois par minute, sans raison valable
- Interroger un point de terminaison /index volumineux sans délai entre les requêtes, indéfiniment
- Importer ou exporter une tonne de données sans reculer en cas d'erreurs
Vous devez limiter le débit de votre API, avec des limites plus strictes pour les opérations coûteuses. Il est également judicieux de se réserver la possibilité de désactiver temporairement l'API pour certains clients, afin de soulager votre système backend s'il est vraiment saturé.
Incluez des métadonnées de limitation de débit dans vos réponses API. Les en-têtes X-Limit-Remaining et Retry-After fournissent aux clients les informations dont ils ont besoin pour utiliser votre API de manière respectueuse et vous permettent de définir des limites de débit plus strictes que vous ne pourriez le faire autrement.
Pagination
Presque toutes les API doivent traiter une longue liste d'enregistrements. Parfois, cette liste est très longue (par exemple, l'API Zendesk /tickets peut contenir des millions de tickets). Comment pouvez-vous servir ces enregistrements ?
Une approche naïve SELECT * FROM tickets WHERE... épuisera votre mémoire disponible (si ce n'est pas dans la base de données, alors dans la couche applicative où vous essayez de sérialiser cette liste d'un million d'éléments). Vous ne pouvez tout simplement pas servir tous les tickets en une seule requête. Vous devez plutôt paginer.
La façon la plus simple de paginer est d'utiliser des pages (ou des « décalages », de manière plus générique). Lorsque vous cliquez sur /tickets, vous obtenez les dix premiers tickets du compte. Pour en obtenir davantage, vous devez cliquer soit sur /tickets?page=2, soit sur /tickets?offset=20. Cela est facile à mettre en œuvre, car le serveur peut simplement ajouter OFFSET 20 LIMIT 10 à la fin de la requête de base de données. Mais cela ne fonctionne pas avec un nombre très élevé d'enregistrements. Les bases de données relationnelles doivent compter votre décalage à chaque fois, de sorte que chaque page que vous servez est un peu plus lente que la précédente. Lorsque votre décalage atteint des centaines de milliers, cela devient un véritable problème.
La solution est la « pagination basée sur le curseur ». Au lieu de passer offset=20 pour obtenir la deuxième page, vous prenez le dernier ticket de la première page (par exemple, avec l'ID 32) et vous passez cursor=32. L'API renverra alors les dix tickets suivants, en commençant par le ticket numéro 32. Au lieu d'utiliser OFFSET, la requête devient WHERE id > curseur ORDER BY id LIMIT 10. Cette requête est tout aussi rapide, que vous soyez au début de la collection ou à des centaines de milliers de tickets, car la base de données peut trouver instantanément la position (indexée) de votre ticket curseur au lieu d'avoir à compter tout le décalage.
Vous devez toujours utiliser la pagination basée sur le curseur pour les ensembles de données qui pourraient finir par être volumineux. Même si cela est plus difficile à comprendre pour les consommateurs, lorsque vous rencontrez des problèmes de mise à l'échelle, vous devrez peut-être passer à la pagination basée sur le curseur, et le coût de cette modification est souvent très élevé. Cependant, je pense qu'il est acceptable d'utiliser la pagination basée sur les pages ou les décalages dans les autres cas.
Il est généralement judicieux d'inclure un champ next_page dans les réponses de votre liste API. Cela évite aux consommateurs d'avoir à déterminer eux-mêmes le numéro de la page suivante ou le curseur.
Champs facultatifs et GraphQL
Si certaines parties de votre réponse API sont coûteuses à fournir, rendez-les facultatives. Par exemple, si la récupération du statut d'abonnement de l'utilisateur nécessite que votre backend effectue un appel API, envisagez de faire en sorte que votre point de terminaison /users/:id ne renvoie pas l'abonnement à moins que la requête ne transmette un paramètre include_subscription. De manière plus générale, vous pouvez utiliser un paramètre de tableau includes avec tous vos champs facultatifs. Cette approche est souvent utilisée pour les enregistrements associés (par exemple, vous pouvez passer includes: [posts] à votre requête utilisateur pour obtenir les publications de l'utilisateur dans la réponse).
Cela fait partie de l'idée derrière GraphQL, un style d'API où, au lieu d'atteindre différents points de terminaison par opération, vous créez une seule requête avec toutes les données dont vous avez besoin et le backend s'en charge.
Je n'aime pas beaucoup GraphQL, pour trois raisons. Premièrement, il est totalement incompréhensible pour les non-ingénieurs (et pour de nombreux ingénieurs). Une fois que vous l'avez appris, c'est un outil comme un autre, mais la barrière à l'entrée est tellement plus élevée que GET /users/1. Deuxièmement, je n'aime pas donner aux utilisateurs la liberté de créer des requêtes arbitraires. Cela complique la mise en cache et augmente le nombre de cas limites auxquels vous devez réfléchir. Troisièmement, d'après mon expérience, la mise en œuvre du backend est beaucoup plus compliquée que celle d'une API REST standard.
Je n'ai pas une aversion profonde pour GraphQL. Je l'ai utilisé pendant environ six mois dans divers contextes et je suis loin d'être un expert. Je suis sûr qu'il existe des cas d'utilisation où il offre suffisamment de flexibilité pour en valoir la peine. Mais pour l'instant, je ne l'utiliserais que lorsque c'est absolument nécessaire.
API internes
Tout ce que j'ai dit jusqu'à présent concerne les API publiques. Qu'en est-il des API internes, c'est-à-dire celles qui ne sont utilisées que par vos collègues au sein d'une entreprise donnée ? Certaines des hypothèses que j'ai formulées ci-dessus ne s'appliquent pas aux API internes. Par exemple, vos consommateurs sont généralement des ingénieurs logiciels professionnels. Il est également possible d'apporter des modifications radicales en toute sécurité, car (a) vous avez souvent un nombre d'utilisateurs nettement inférieur et (b) vous avez la possibilité d'intervenir et de fournir un nouveau code à tous ces utilisateurs. Vous pouvez exiger une forme d'authentification aussi complexe que vous le souhaitez.
Cependant, les API internes peuvent toujours être à l'origine d'incidents et doivent rester idempotentes pour les opérations clés.
Résumé
- Les API sont difficiles à créer car elles sont rigides, mais elles doivent être faciles à adopter.
- La principale responsabilité des responsables de la maintenance des API est de NE PAS PERTURBER L'ESPACE UTILISATEUR. N'apportez jamais de modifications radicales aux API publiques.
- La gestion des versions de votre API vous permet d'apporter des modifications, mais impose des obstacles importants en termes de mise en œuvre et d'adoption.
- Si votre produit a suffisamment de valeur, la qualité de votre API n'a pas vraiment d'importance, les gens l'utiliseront de toute façon.
- Si votre produit est suffisamment mal conçu, peu importe le soin que vous apportez à la conception de votre API, elle sera probablement mauvaise.
- Votre API doit prendre en charge des clés API simples pour l'authentification, car bon nombre de vos utilisateurs ne seront pas des ingénieurs professionnels.
- Les requêtes qui entraînent une action (en particulier les actions à haut risque comme les paiements) doivent inclure une sorte de clé d'idempotence afin de sécuriser les nouvelles tentatives.
- Votre API sera toujours une source d'incidents. Assurez-vous de mettre en place des limites de débit et des coupe-circuits.
- Utilisez la pagination par curseur pour les ensembles de données qui pourraient finir par être très volumineux.
- Rendez les champs coûteux facultatifs et désactivés par défaut, mais (à mon avis) GraphQL est excessif.
- Les API internes sont différentes à certains égards (car vos consommateurs sont très différents).
Qu'est-ce que je n'ai pas abordé ? Je n'ai pas beaucoup parlé de REST vs SOAP, ou JSON vs XML, car je ne pense pas que ces questions soient particulièrement importantes. J'aime bien REST et JSON, mais je n'ai pas d'avis tranché à ce sujet. Je n'ai pas non plus mentionné le schéma OpenAPI. C'est un outil utile, mais je pense qu'il est tout à fait possible de rédiger la documentation de votre API en Markdown si vous le souhaitez.
edit : cet article a fait l'objet de nombreuses discussions et commentaires sur Hacker News et Reddit. Les commentateurs ont souligné que j'aurais dû mentionner PUT dans ma section sur l'idempotence, car il est censé être idempotent de par sa conception. Je suppose que c'est vrai, mais je ne l'ai pas beaucoup vu en pratique et, à mon avis, il n'y a rien dans le verbe HTTP qui le rende intrinsèquement plus idempotent que POST. L'utilisation de Redis comme magasin d'idempotence a également suscité certaines inquiétudes, car il est impossible d'obtenir des opérations atomiques sûres qui coordonnent Redis et votre base de données. C'est une préoccupation légitime pour les paiements ou les domaines à haut risque, mais ajouter Redis à une API non idempotente existante reste bien mieux que rien.
Source : "Everything I know about good API design"
Et vous ?

Voir aussi :



Vous avez lu gratuitement 1 242 articles depuis plus d'un an.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.