GitHub REST API Delphi-client via sgcOpenAPI

GitHub onderhoudt een van de grootste OpenAPI-beschrijvingen die ergens gepubliceerd zijn, en geeft die uit onder de MIT-licentie. sgcOpenAPI levert geen met de hand geschreven GitHub-component, het levert een generator. Eén commandoregel over api.github.com.json produceert één Pascal-unit met 1.225 methodes, een getypeerde response-klasse voor elk daarvan, en een GetOpenAPIClient-functie die je een kant-en-klare client geeft.

GitHub + sgcOpenAPI

De cijfers hieronder zijn gemeten door de generator over de huidige beschrijving te draaien en het resultaat te compileren, niet geschat.

Bron-spec

descriptions/api.github.com/api.github.com.json in github/rest-api-description, opgegeven als OpenAPI 3.0.3. Er is geen conversiestap nodig.

Wat eruit komt

813 paths worden 1.225 methodes en 1.134 response-klassen, naast 3.250 modelklassen, in één unit van ongeveer 274.000 regels.

Authenticatie

Genereer met -a 2 en zet Authentication.Token.BearerToken tijdens runtime. Dat dekt zowel een personal access token als een installation token.

Het compileert

De gegenereerde unit bouwt schoon op RAD Studio 12 voor Win32, met niets op het library-pad behalve de map Source van sgcOpenAPI.

Draai de generator

GitHub publiceert meerdere varianten van dezelfde beschrijving. api.github.com.json beschrijft de gehoste dienst en ghes-3.x.json beschrijft GitHub Enterprise Server. Genereer uit de variant waar je op mikt.

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

File successfully created github.pas

-i neemt een lokaal bestand of een URL en accepteert JSON en YAML. -o is de Pascal-unit die geschreven wordt, en de unit krijgt de naam van dat bestand. -a 2 kiest token-authenticatie, zodat elke gegenereerde methode Authorization: Bearer meestuurt. Hetzelfde uitvoerbare bestand is een GUI-wizard als je het zonder parameters start, en het eindigt met 0 bij succes, 5 bij een verkeerd invoerbestand, 6 bij een verkeerd uitvoerbestand en 7 wanneer het document niet kan worden omgezet naar een geldig OpenAPI 3-document.

Voeg de gegenereerde .pas toe aan je project en zet hem in een uses-clausule. Er is geen component te installeren, want sgcOpenAPI registreert er geen en levert geen design-time package.

Lijst je repositories op

GitHub schrijft zijn operation-id’s met schuine strepen en koppeltekens, zoals in repos/list-for-authenticated-user. Die tekens mogen niet in een Pascal-identifier staan, dus de generator haalt ze weg en de methode komt binnen als reposlistforauthenticateduser.

uses
  github;   // de unit die je zojuist genereerde

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;

Een endpoint dat een array teruggeeft, krijgt een response waarvan Successful een afstammeling van TsgcOpenAPIArray is met een getypeerde Items, hier TArray<TsgcOpenAPI_repository_Class>. De basis-URL komt uit de servers-entry, dus de gegenereerde constructor zet https://api.github.com er al in. Paginering wordt niet voor je verborgen: aPer_page en aPage zijn gewone argumenten en je loopt zelf door de pagina’s heen.

Als die namen in kleine letters je storen, genereer dan met -m 1, dan worden de methodes naar de summary van de operatie vernoemd, of met -m 2 om ze naar het endpoint te vernoemen.

Maak een issue aan en lijst pull requests op

Path-parameters komen binnen als eerste argumenten, in de volgorde waarin het document ze opgeeft. De request-body komt binnen als string, om de reden die hieronder wordt uitgelegd.

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;

Elke response-klasse draagt Successful plus één property per statuscode die het document opgeeft, dus Error304, Error401, Error403 en Error422 staan klaar om te lezen wanneer de aanroep mislukt. Een status die GitHub met een benoemd schema beschrijft wordt een klasse, en een status die het met niets beschrijft wordt een gewone string. De foutproperty wordt op aanvraag aangemaakt, dus hij is nooit nil en je toetst IsSuccessful in plaats van het object.

De underscore in _message is geen typefout. message is een van de 68 gereserveerde Pascal-woorden die de generator escapet, dus een schemaveld met die naam komt binnen met een underscore ervoor. Hetzelfde gebeurt met type, object, default, index en de rest van de lijst, die allemaal ergens in de schema’s van GitHub voorkomen.

Wat de gegenereerde unit bevat

De unit spiegelt de beschrijving. Er wordt niets geselecteerd, dus alles wat GitHub documenteert zit erin en alles wat GitHub weglaat zit er niet in.

Elke gedocumenteerde operatie

1.225 methodes, over repositories en contents, issues en pull requests, Actions en check runs, packages, organisaties en teams, GitHub Apps, code scanning en de rest van het oppervlak.

Eén response-klasse per methode

Elke klasse stamt af van TsgcOpenAPIResponse en erft IsSuccessful, dat waar is voor 200 tot en met 299, samen met ResponseCode en ResponseError.

3.250 modelklassen

TsgcOpenAPI_repository_Class, TsgcOpenAPI_issue_Class, TsgcOpenAPI_basic_error_Class, TsgcOpenAPI_validation_error_Class en elk ander schema in de components-sectie.

Tags als commentaar

De tags van GitHub komen eruit als commentaar dat de methodes binnen die ene client-klasse groepeert. Ze worden geen aparte klassen, dus alles hangt aan GetOpenAPIClient.

De documentatie uit de spec

De eigen beschrijvingen van GitHub komen door als Pascal-commentaar boven elke methode en property, zodat de IDE ze toont waar je ze gebruikt.

Ook Enterprise Server

De ghes-3.x-beschrijvingen genereren op dezelfde manier. Houd één gegenereerde unit per doel aan als je met allebei praat.

Vier dingen die je moet weten

Alle vier komen uit een echte generatierun over de huidige beschrijving.

De unit is heel groot

Ongeveer 274.000 regels en 12 MB, de grootste van de publieke specificaties die we hier genereren. Hij compileert in minder dan twee seconden, maar de editor van de IDE is traag bij een bestand van dat formaat. -x laat operaties weg die je opgeeft als "VERB endpoint" en -p haalt daarna de klassen weg die geen enkele overgebleven operatie gebruikt.

De meeste request-bodies zijn strings

343 operaties geven een application/json-body op, maar bijna allemaal beschrijven ze die als een anoniem inline-object in plaats van als een benoemd schema. Een inline-object heeft geen naam om een klasse aan te ontlenen, dus de parameter is const aBody: string en jij bouwt de JSON. De handvol die wel naar een benoemd schema verwijst, krijgt wel een getypeerde klasse.

273 waarschuwingen, en die zijn het lezen waard

De meeste gaan over compositie zonder discriminator-mapping, waarbij de gegenereerde klasse één member per tak draagt. Een paar melden een $ref die het document niet oplost, en een paar melden een operatie die twee geslaagde statussen opgeeft, waarvan er maar één wordt gegenereerd. De generator zegt welke, in plaats van stilzwijgend te kiezen.

Rate limits en app-tokens handel je zelf af

De gegenereerde client is een getrouwe HTTP-client en niets meer. Hij cachet geen ETag-waarden, probeert het niet opnieuw bij een 403, en vernieuwt geen installation token van een GitHub App. Lees ResponseCode, gebruik OnBeforeRequest om een header voor een conditioneel verzoek toe te voegen, en maak installation tokens aan met de apps-methodes die de unit al bevat.

Vanuit de blog

OpenAPI Delphi-parser

Hoe de lezer echte specificaties afhandelt, inclusief de compositie-keywords achter de meeste waarschuwingen.

Lees post →

OpenAPI-client en parser

De begeleidende post die de gegenereerde client introduceert en de lezer waarop hij is gebouwd.

Lees post →

sgcOpenAPI 2026.6

Release-notes voor de huidige versie, met de generator-opties en de wijzigingen in de lezer.

Lees post →
De beste deal: All-AccessElk eSeGeCe-product, inclusief Premium-ondersteuning, vanaf €1,059 per jaar.
Bekijk de All-Access-prijzen

Bouw vandaag nog je GitHub-automatisering

sgcOpenAPI levert de lezer, de code-generator, de OpenAPI-server en kant-en-klare SDK’s voor Amazon, Azure, Google en Microsoft. Eén product, drie tiers, geprijsd per gebruiker in plaats van per functie.