Client Delphi pour l'API REST GitHub via sgcOpenAPI

GitHub maintient l'une des plus grandes descriptions OpenAPI publiées où que ce soit, et la diffuse sous licence MIT. sgcOpenAPI ne livre pas de composant GitHub écrit à la main, il livre un générateur. Une seule ligne de commande sur api.github.com.json produit une seule unité Pascal avec 1 225 méthodes, une classe de réponse typée pour chacune d'elles, et une fonction GetOpenAPIClient qui vous rend un client prêt à l'emploi.

GitHub + sgcOpenAPI

Les chiffres ci-dessous ont été mesurés en lançant le générateur sur la description actuelle puis en compilant le résultat, ils ne sont pas estimés.

Spec source

descriptions/api.github.com/api.github.com.json dans github/rest-api-description, déclaré en OpenAPI 3.0.3. Aucune étape de conversion n'est nécessaire.

Ce qui en sort

813 chemins deviennent 1 225 méthodes et 1 134 classes de réponse, à côté de 3 250 classes de modèle, dans une seule unité d'environ 274 000 lignes.

Authentification

Générez avec -a 2 et définissez Authentication.Token.BearerToken à l'exécution. Cela couvre aussi bien un personal access token qu'un installation token.

Ça compile

L'unité générée compile sans erreur sur RAD Studio 12 pour Win32, avec rien d'autre sur le chemin des bibliothèques que le dossier Source de sgcOpenAPI.

Lancer le générateur

GitHub publie plusieurs déclinaisons de la même description. api.github.com.json décrit le service hébergé et ghes-3.x.json décrit GitHub Enterprise Server. Générez à partir de celle que vous ciblez.

> sgcOpenAPI.exe -i "api.github.com.json" -o "github.pas" -a 2

File successfully created github.pas

-i prend un fichier local ou une URL et accepte le JSON et le YAML. -o est l'unité Pascal à écrire, et l'unité porte le nom de ce fichier. -a 2 sélectionne l'authentification par token, si bien que chaque méthode générée envoie Authorization: Bearer. Le même exécutable est un assistant graphique quand il est démarré sans paramètre, et il sort avec 0 en cas de succès, 5 sur un fichier d'entrée invalide, 6 sur un fichier de sortie invalide et 7 quand le document ne peut pas être transformé en document OpenAPI 3 valide.

Ajoutez le .pas généré à votre projet et mettez-le dans une clause uses. Il n'y a aucun composant à installer, parce que sgcOpenAPI n'en enregistre aucun et ne livre pas de package de conception.

Lister vos dépôts

GitHub écrit ses operation ids avec des barres obliques et des traits d'union, comme dans repos/list-for-authenticated-user. Ces caractères ne peuvent pas figurer dans un identifiant Pascal, donc le générateur les supprime et la méthode arrive sous le nom reposlistforauthenticateduser.

uses
  github;   // l'unité que vous venez de générer

procedure TfrmGitHub.btnReposClick(Sender: TObject);
var
  oResponse: TsgcOpenAPI_reposlistforauthenticateduser_Response;
  oRepo: TsgcOpenAPI_repository_Class;
begin
  GetOpenAPIClient.Authentication.Token.BearerToken := txtToken.Text;

  oResponse := GetOpenAPIClient.reposlistforauthenticateduser(
    'private', 'owner', 'all', 'full_name', '', 100, 1);
  try
    if oResponse.IsSuccessful then
    begin
      for oRepo in oResponse.Successful.Items do
        memoLog.Lines.Add(oRepo.Full_name + '  ' + oRepo.Description);
    end
    else
      memoLog.Lines.Add(IntToStr(oResponse.ResponseCode) + ' ' +
        oResponse.ResponseError);
  finally
    oResponse.Free;
  end;
end;

Un endpoint qui retourne un tableau reçoit une réponse dont le Successful est un descendant de TsgcOpenAPIArray avec un Items typé, ici TArray<TsgcOpenAPI_repository_Class>. L'URL de base sort de l'entrée servers, donc le constructeur généré définit déjà https://api.github.com. La pagination ne vous est pas cachée : aPer_page et aPage sont de simples arguments et vous bouclez vous-même sur les pages.

Si les noms en minuscules vous gênent, générez avec -m 1 et les méthodes sont nommées d'après le résumé de l'opération, ou avec -m 2 pour les nommer d'après l'endpoint.

Créer une issue et lister les pull requests

Les paramètres de chemin arrivent en premiers arguments, dans l'ordre où le document les déclare. Le corps de requête arrive sous forme de chaîne, pour la raison expliquée plus bas.

var
  oIssue: TsgcOpenAPI_issuescreate_Response;
  oPulls: TsgcOpenAPI_pullslist_Response;
begin
  oIssue := GetOpenAPIClient.issuescreate('octocat', 'Hello-World',
    '{"title":"Memory leak in the HTTP/2 reader",' +
    '"body":"Repro steps: ...","labels":["bug","http2"]}');
  try
    if oIssue.IsSuccessful then
      memoLog.Lines.Add('filed issue #' +
        IntToStr(oIssue.Successful.Number) + ' ' + oIssue.Successful.Html_url)
    else
      memoLog.Lines.Add(oIssue.Error422._message);
  finally
    oIssue.Free;
  end;

  oPulls := GetOpenAPIClient.pullslist('octocat', 'Hello-World',
    'open', 'updated');
  try
    memoLog.Lines.Add(IntToStr(oPulls.ResponseCode));
  finally
    oPulls.Free;
  end;
end;

Chaque classe de réponse porte Successful plus une propriété par code de statut que le document déclare, si bien que Error304, Error401, Error403 et Error422 sont là à lire quand l'appel échoue. Un statut que GitHub décrit avec un schéma nommé devient une classe, et un statut qu'il décrit sans rien devient une simple chaîne. La propriété d'erreur est créée à la demande, elle n'est donc jamais nil et vous testez IsSuccessful plutôt que l'objet.

Le tiret bas de _message n'est pas une faute de frappe. message fait partie des 68 mots réservés de Pascal que le générateur échappe, donc un champ de schéma portant ce nom arrive avec un tiret bas en tête. Il en va de même pour type, object, default, index et le reste de la liste, qui apparaissent tous quelque part dans les schémas de GitHub.

Ce que contient l'unité générée

L'unité reflète la description. Rien n'est trié à la main, donc tout ce que GitHub documente est présent et tout ce que GitHub laisse de côté ne l'est pas.

Chaque opération documentée

1 225 méthodes, qui couvrent les dépôts et leur contenu, les issues et les pull requests, Actions et les check runs, les packages, les organisations et les équipes, les GitHub Apps, le code scanning et le reste de la surface.

Une classe de réponse par méthode

Chacune descend de TsgcOpenAPIResponse et hérite de IsSuccessful, qui est vrai de 200 à 299, ainsi que de ResponseCode et ResponseError.

3 250 classes de modèle

TsgcOpenAPI_repository_Class, TsgcOpenAPI_issue_Class, TsgcOpenAPI_basic_error_Class, TsgcOpenAPI_validation_error_Class et tous les autres schémas de la section components.

Les tags en commentaires

Les tags de GitHub sont émis comme des commentaires qui regroupent les méthodes à l'intérieur de la classe client unique. Ils ne deviennent pas des classes séparées, donc tout part de GetOpenAPIClient.

La documentation de la spec

Les descriptions de GitHub sont reportées en commentaires Pascal au-dessus de chaque méthode et de chaque propriété, si bien que l'IDE les affiche là où vous les utilisez.

Enterprise Server aussi

Les descriptions ghes-3.x se génèrent de la même façon. Gardez une unité générée par cible si vous parlez aux deux.

Quatre choses à savoir

Toutes les quatre sont sorties d'une vraie génération sur la description actuelle.

L'unité est très volumineuse

Environ 274 000 lignes et 12 Mo, la plus grosse des spécifications publiques que nous générons ici. Elle compile en moins de deux secondes, mais l'éditeur de l'IDE est lent avec un fichier de cette taille. -x retire les opérations que vous listez sous la forme "VERB endpoint" et -p supprime ensuite les classes qu'aucune opération restante n'utilise.

La plupart des corps de requête sont des chaînes

343 opérations déclarent un corps application/json, mais presque toutes le décrivent comme un objet anonyme en ligne plutôt que comme un schéma nommé. Un objet en ligne n'a pas de classe à nommer, donc le paramètre est const aBody: string et vous construisez le JSON. La poignée d'opérations qui référencent un schéma nommé reçoivent bien une classe typée.

273 avertissements, et ils valent la lecture

La plupart portent sur la composition sans mapping de discriminateur, où la classe générée porte un membre par branche. Quelques-uns signalent un $ref que le document ne résout pas, et quelques-uns signalent une opération qui déclare deux statuts de succès, dont un seul est généré. Le générateur dit lequel plutôt que de choisir en silence.

Les quotas et les tokens d'application sont à votre charge

Le client généré est un client HTTP fidèle et rien de plus. Il ne met pas en cache les valeurs ETag, ne réessaie pas sur 403 et ne rafraîchit pas un installation token de GitHub App. Lisez ResponseCode, utilisez OnBeforeRequest pour ajouter un en-tête de requête conditionnelle, et fabriquez les installation tokens avec les méthodes apps que l'unité contient déjà.

Depuis le blog

Parseur OpenAPI Delphi

Comment le lecteur gère les spécifications réelles, y compris les mots-clés de composition à l'origine de la plupart des avertissements.

Lire le billet →

Client OpenAPI + parseur

Le billet compagnon qui présente le client généré et le lecteur sur lequel il repose.

Lire le billet →

sgcOpenAPI 2026.6

Notes de release de la version actuelle, avec les options du générateur et les changements du lecteur.

Lire le billet →
Meilleur rapport qualité-prix : All-AccessTous les produits eSeGeCe, Support Premium inclus, à partir de €1,059/an.
Voir les tarifs All-Access

Construisez votre automatisation GitHub aujourd'hui

sgcOpenAPI livre le lecteur, le générateur de code, le serveur OpenAPI et des SDK préconçus pour Amazon, Azure, Google et Microsoft. Un produit, trois niveaux, au prix par poste plutôt que par fonctionnalité.