Aller au contenu principal

Ce que le moteur lit, et comment le façonner.

Le support OpenAPI maximal est une obligation affichée du projet : une construction non supportée d’une version supportée est traitée comme un défaut, pas comme une limite. Ce guide dit exactement ce qui est lu, et documente les quatre leviers qui façonnent le document rendu — les overlays déclarés par l’hôte, ceux écrits par le lecteur, le masquage, le changelog local. La page Contrôle du schéma est la version courte.

Versions et formats

  • OpenAPI 3.0.x, 3.1.x, 3.2.x sont rendus nativement — y compris la méthode query de 3.2, les paramètres in: querystring et $self. JSON ou YAML.
  • Les mots-clés JSON Schema 2020-12 sont rendus plutôt qu’écartés en silence, dans les vues de schéma comme dans les exemples générés.
  • Webhooks et callbacks sont normalisés et rendus comme des opérations — voir plus bas.
  • Les sections de tags 3.2 sont rendues en entier : le summary d’un tag titre sa section de nav, parent l’imbrique (un parent immédiatement suivi de ses enfants, pastilles de comptage et points de changement couvrant les sous-groupes), et kind décide ce qu’un tag estnav ou absent fait une section, toute autre valeur (badge, audience, ou la vôtre) devient un badge sur les opérations qui le portent. Les deux formes que la spec interdit sont raccrochées, jamais fatales : un parent inconnu comme un cycle de parents se détachent vers la racine.
  • Les links de réponses et externalDocs sont rendus aussi : un Link Object reçoit une navigation « aller à l’opération » (ses expressions runtime affichées comme documentation, jamais évaluées), et externalDocs se rend aux niveaux racine, tag, opération et schéma.
  • Les références circulaires sont gérées partout : les nœuds cycliques sont marqués dans le modèle, et le rendu déplie paresseusement avec un budget de profondeur (trois niveaux, puis un « déplier » explicite). Aucune récursion sans borne, ni dans la doc ni dans les exemples générés. Les cycles profonds font aussi partie de ce que l’audit signale à l’auteur.

Swagger 2.0, converti au chargement

Un document déclarant swagger: "2.0" est converti en OpenAPI 3.0.4 avant que quoi que ce soit d’autre le lise — rien en aval ne sait que 2.0 existe. host/basePath/schemes deviennent des servers, les paramètres in: body et in: formData deviennent des request bodies, les definitions déménagent dans components avec chaque $ref réécrit, les définitions de sécurité et les noms de flows prennent leur forme 3.x.

La conversion est honnête sur ses limites : les quelques valeurs de collectionFormat que 3.0 ne sait pas exprimer retombent sur la virgule, l’original est consigné dans le document, et l’audit rapporte chaque approximation. Le panneau de diagnostics des réglages indique qu’une conversion a eu lieu.

Overlays : corriger un schéma qui n’est pas à vous

openapi.overlays déclare des documents OpenAPI Overlay 1.1 appliqués au chargement, chaque entrée étant une URL (JSON ou YAML) ou l’objet overlay lui-même, porté par la config :

api-doc-config
{
  "openapi": {
    "url": "https://vendor.example.com/openapi.json",
    "overlays": [
      {
        "overlay": "1.1.0",
        "info": { "title": "Docs fixes", "version": "1" },
        "actions": [
          { "target": "$.paths['/pets'].get", "update": { "summary": "Lister les animaux" } },
          { "target": "$.paths['/internal']", "remove": true }
        ]
      }
    ]
  }
}

Ce que le moteur garantit :

  • Les cibles sont du JSONPath RFC 9535 complet — filtres, tranches, unions, descente et fonctions d’extension, pas seulement le sous-ensemble enfant/joker des exemples de la spec Overlay.
  • Trois actions. update fusionne (objets récursivement, tableaux par concaténation, primitifs par remplacement), remove: true supprime le nœud de son parent, et copy — nouveauté 1.1 — fusionne un nœud du document lui-même dans chaque cible. Un overlay 1.0 est accepté et lu avec les règles 1.1.
  • Les overlays s’appliquent au source parsé, avant la conversion Swagger 2.0 — un overlay s’écrit contre le fichier que son auteur a sous les yeux, qui peut très bien être un 2.0. Tout l’aval voit un seul document, le document corrigé : l’audit note celui-là, et le bouton de téléchargement du schéma sert celui-là — vos lecteurs ne peuvent jamais récupérer par accident le fichier non corrigé.
  • L’ordre est l’ordre de déclaration : les overlays de la racine d’abord, puis ceux de la spec active en multi-spec — ils s’accumulent, comme hide.
  • Rien n’est silencieux. Une cible qui ne matche rien, un update qui ne peut pas fusionner là où il pointe, une URL qui ne charge pas — chaque écart est listé dans les diagnostics des réglages et répété en console. Un overlay ne casse jamais le chargement.

Quand c’est le lecteur qui est bloqué

La section précédente est le levier de l’intégrateur. Le lecteur dispose du même, pour la même raison à plus petite échelle : un paramètre typé string que le serveur refuse tant qu’il n’est pas un nombre, une entrée servers jamais remplie, un champ requis que l’API a discrètement cessé d’exiger. Le propriétaire du schéma, c’est une autre équipe, une autre entreprise ou une file de tickets — et tant qu’il n’a pas bougé, la console d’essai construit ses requêtes sur un modèle que tout le monde sait faux.

Corriger ce schéma en local — une section du panneau de réglages — prend un document Overlay 1.1 écrit par le lecteur et l’applique après tout ce que la configuration a déclaré. Même moteur, même JSONPath, mêmes diagnostics ; la seule nouveauté est qui a écrit le document, et où il est gardé.

Quatre boutons, chacun exactement ce qu’il annonce :

  • Vérifier exécute le document à blanc contre le schéma déjà en mémoire et rapporte, action par action, combien de nœuds la cible touche. Rien n’est téléchargé, rien n’est écrit, rien n’est rechargé — « la cible ne touche aucun nœud » s’apprend donc avant de s’y engager.
  • Enregistrer et recharger persiste le document puis recharge la page. Les overlays s’appliquent au source parsé avant que quoi que ce soit le lise : appliquer un correctif, c’est rejouer le pipeline — la même posture qu’un changement de spec. Rien n’est rafistolé à chaud dans votre dos.
  • Télécharger produit overlay-{specId}.json : un fichier Overlay 1.1 standard, et c’est tout l’intérêt. La fin naturelle d’un contournement, c’est l’amont — joignez-le au rapport de bug, ouvrez la pull request, ou passez-le à qui maintient openapi.overlays.
  • Retirer le correctif supprime le document et recharge, derrière une confirmation.

L’éditeur prend du JSON uniquement. Le canal openapi.overlays par URL, lui, accepte toujours le YAML — il passe par le ref-parser — mais l’app n’embarque aucun sérialiseur YAML : une zone de texte qui lirait du YAML et ne saurait réémettre que du JSON ferait mentir le bouton de téléchargement sur ce qui a été tapé.

Rien d’un correctif local n’a le droit d’être discret, parce que le risque que cette fonctionnalité crée, c’est justement d’oublier qu’on en a posé un : tant qu’un correctif est actif, l’en-tête porte un badge permanent « Schéma corrigé » qui ouvre l’éditeur, et les diagnostics des réglages listent le document du lecteur à côté de ceux de l’hôte — actions et avertissements compris, signalé comme le sien.

Le reste du contrat, d’une traite : un document par spec, plafonné à 64 Ko (au-delà, l’enregistrement est refusé et rien n’est écrit) ; stocké dans le navigateur du lecteur sous la clé de la spec, donc cloisonné par spec et effacé par la purge des réglages ; aucun droit de veto pour l’hôte — cela ne change que la vue d’un lecteur dans un navigateur, hide s’applique toujours ensuite, et un hôte qui soigne sa documentation n’y perd rien. L’audit note le document corrigé, ce qui est bien le but ; le bouton de téléchargement du schéma est l’exception assumée et sert toujours le fichier publié par l’API, parce que c’est celui-là qu’on transmet à quelqu’un d’autre.

Une clé de config existe côté hôte, et elle amorce plutôt qu’elle ne gouverne : openapi.userOverlay tend à l’éditeur du lecteur un correctif de départ (null par défaut). Par spec, elle remplace le document de la racine au lieu de s’empiler, et ré-amorcer avec un autre document jette les modifications locales du lecteur — l’éditeur reste au lecteur, l’hôte ne propose que son état d’ouverture.

Cacher les endpoints internes

Deux canaux, cumulables :

  • Dans le schéma"x-apiglow-hide": true sur une opération, un Path Item ou une entrée de tags.
  • Dans la config — des motifs openapi.hide, * accepté comme joker : "tag:Internal", "DELETE /admin/*", "/admin/*", ou un operationId — l’id de repli {method}-{slug} matche aussi, donc une opération sans operationId reste nommable.

Le filtrage a lieu à la normalisation du document : une opération cachée est donc absente d’un coup de la nav, de la recherche, de la pagination, du diff du changelog et de chaque export — llms.txt compris. Deux endroits voient encore le document complet, à dessein : l’audit (un auteur veut la vue entière ; les constats sur opérations cachées sont étiquetés au lieu d’être liés) et l’onglet réseau du navigateur. C’est du masquage documentaire, pas de la sécurité : le navigateur télécharge le schéma complet, et n’importe qui peut le lire. N’en faites jamais un contrôle d’accès.

Le changelog local du schéma

Le lecteur qui revient obtient « ce qui a changé depuis ma dernière visite » : au chargement, le document est comparé à une empreinte des opérations que ce lecteur a vues en dernier, stockée dans son propre navigateur. Une modale liste les opérations ajoutées, retirées et modifiées — avec les deux versions du schéma et la date de la dernière visite — et des badges marquent les opérations ajoutées ou modifiées dans la nav et dans la doc, avec un nom accessible, jamais la couleur seule. Ouvrir la modale marque le diff comme vu ; le changelog suivant repart de là.

Aucun service derrière, rien à configurer : les empreintes sont des instantanés compacts par schéma dans l’IndexedDB du lecteur, plafonnés en LRU (vingt schémas ; un enregistrement trop gros n’est simplement pas stocké). Les limites découlent du design, et méritent d’être connues : une première visite n’a rien à comparer, une empreinte évincée coûte exactement un changelog, et le diff compare des empreintes bornées — un changement enfoui sous le budget de profondeur n’est pas signalé. Pour des garanties de contrat, diffez les fichiers de schéma en CI ; ceci est une aide à la lecture, pour des humains. La page de fonctionnalité montre ce que voient les lecteurs.

Webhooks, callbacks, et le simulateur

Les webhooks (la clé webhooks de 3.1+) se rendent comme des opérations, dans leur propre section de nav ; les callbacks se rendent dans l’opération qui les déclare. À la place d’une console d’essai, une page de webhook porte un simulateur : il envoie le payload d’exemple vers une URL de récepteur que vous fournissez — votre endpoint en développement, pas l’API — pour exercer un récepteur sans attendre l’événement réel.

Le simulateur résout les {{variables}} de l’environnement actif dans l’URL, les en-têtes et le payload — une variable manquante bloque l’envoi, comme partout — mais n’injecte délibérément aucun identifiant : l’appel vise votre récepteur, pas l’API. Il honore tryIt.proxyUrl quand un proxy est configuré, et pour un récepteur qui n’autorise aucune origine, une bascule fire-and-forget envoie en mode no-cors : l’événement est livré, la réponse est opaque, et les en-têtes que ce mode écarte sont nommés avant l’envoi plutôt que perdus sans bruit.