Client Delphi per la REST API di GitHub via sgcOpenAPI

GitHub mantiene una delle più grandi descrizioni OpenAPI mai pubblicate, e la rilascia con licenza MIT. sgcOpenAPI non include un componente GitHub scritto a mano, include un generatore. Una sola riga di comando su api.github.com.json produce una singola unit Pascal con 1.225 metodi, una classe di response tipizzata per ognuno, e una funzione GetOpenAPIClient che ti consegna un client pronto.

GitHub + sgcOpenAPI

I numeri qui sotto sono stati misurati eseguendo il generatore sulla descrizione attuale e compilando il risultato, non sono stime.

Specifica sorgente

descriptions/api.github.com/api.github.com.json in github/rest-api-description, dichiarata come OpenAPI 3.0.3. Non serve nessun passaggio di conversione.

Cosa ne esce

813 path diventano 1.225 metodi e 1.134 classi di response, insieme a 3.250 classi di modello, in una sola unit di circa 274.000 righe.

Autenticazione

Genera con -a 2 e imposta Authentication.Token.BearerToken a run time. Vale allo stesso modo per un personal access token e per un installation token.

Compila

La unit generata compila pulita su RAD Studio 12 per Win32 con nient'altro nel library path se non la cartella Source di sgcOpenAPI.

Esegui il generatore

GitHub pubblica più varianti della stessa descrizione. api.github.com.json descrive il servizio hosted e ghes-3.x.json descrive GitHub Enterprise Server. Genera da quella che ti interessa.

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

File successfully created github.pas

-i accetta un file locale o un URL, in JSON e in YAML. -o è la unit Pascal da scrivere, e la unit prende il nome da quel file. -a 2 seleziona l'autenticazione a token, così ogni metodo generato invia Authorization: Bearer. Lo stesso eseguibile è un wizard grafico se lo avvii senza parametri, ed esce con 0 quando va a buon fine, con 5 se il file di input non va, con 6 se non va il file di output e con 7 quando il documento non è trasformabile in un documento OpenAPI 3 valido.

Aggiungi al progetto il .pas generato e mettilo in una clausola uses. Non c'è nessun componente da installare, perché sgcOpenAPI non ne registra nessuno e non distribuisce alcun package di design-time.

Elenca i tuoi repository

GitHub scrive i propri operation id con barre e trattini, come in repos/list-for-authenticated-user. Quei caratteri non possono comparire in un identificatore Pascal, quindi il generatore li rimuove e il metodo arriva come reposlistforauthenticateduser.

uses
  github;   // la unit appena generata

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 che restituisce un array ha una response il cui Successful è un discendente di TsgcOpenAPIArray con un Items tipizzato, qui TArray<TsgcOpenAPI_repository_Class>. La base URL arriva dalla voce servers, quindi il costruttore generato imposta già https://api.github.com. La paginazione non ti viene nascosta: aPer_page e aPage sono normali argomenti e il ciclo sulle pagine lo scrivi tu.

Se i nomi tutti in minuscolo ti danno fastidio, genera con -m 1 e i metodi prendono il nome dal summary dell'operazione, oppure con -m 2 per nominarli a partire dall'endpoint.

Crea una issue ed elenca le pull request

I parametri di path arrivano come argomenti iniziali, nell'ordine in cui il documento li dichiara. Il body della request arriva come stringa, per il motivo spiegato qui sotto.

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;

Ogni classe di response porta Successful più una proprietà per ogni status code dichiarato dal documento, quindi Error304, Error401, Error403 ed Error422 sono lì pronti da leggere quando la chiamata fallisce. Uno status che GitHub descrive con uno schema nominato diventa una classe, uno che GitHub non descrive affatto diventa una semplice stringa. La proprietà di errore viene creata su richiesta, quindi non è mai nil e il controllo lo fai su IsSuccessful, non sull'oggetto.

L'underscore in _message non è un refuso. message è una delle 68 parole riservate del Pascal che il generatore protegge, quindi un campo di schema con quel nome arriva con un underscore iniziale. Lo stesso succede a type, object, default, index e al resto dell'elenco, che compaiono tutti da qualche parte negli schemi di GitHub.

Cosa contiene la unit generata

La unit rispecchia la descrizione. Non c'è nessuna selezione a monte, quindi tutto quello che GitHub documenta è presente e tutto quello che GitHub tralascia non c'è.

Ogni operazione documentata

1.225 metodi, che coprono repository e contenuti, issue e pull request, Actions e check run, package, organizzazioni e team, GitHub Apps, code scanning e il resto della superficie.

Una classe di response per metodo

Ognuna discende da TsgcOpenAPIResponse ed eredita IsSuccessful, che è vero da 200 a 299, insieme a ResponseCode e ResponseError.

3.250 classi di modello

TsgcOpenAPI_repository_Class, TsgcOpenAPI_issue_Class, TsgcOpenAPI_basic_error_Class, TsgcOpenAPI_validation_error_Class e ogni altro schema della sezione components.

I tag come commenti

I tag di GitHub vengono emessi come commenti che raggruppano i metodi dentro l'unica classe client. Non diventano classi separate, quindi tutto parte da GetOpenAPIClient.

La documentazione della specifica

Le descrizioni scritte da GitHub arrivano come commenti Pascal sopra ogni metodo e ogni proprietà, così l'IDE te le mostra nel punto in cui li usi.

Anche Enterprise Server

Le descrizioni ghes-3.x si generano allo stesso modo. Tieni una unit generata per ogni target se parli con entrambi.

Quattro cose che vale la pena sapere

Tutte e quattro sono emerse da una generazione reale sulla descrizione attuale.

La unit è molto grande

Circa 274.000 righe e 12 MB, la più grande fra le specifiche pubbliche che generiamo qui. Compila in meno di due secondi, ma l'editor dell'IDE è lento con un file di quelle dimensioni. -x scarta le operazioni che elenchi come "VERB endpoint" e -p rimuove poi le classi che nessuna operazione rimasta usa.

Quasi tutti i request body sono stringhe

343 operazioni dichiarano un body application/json, ma quasi tutte lo descrivono come un oggetto inline anonimo invece che come uno schema nominato. Un oggetto inline non ha una classe a cui dare un nome, quindi il parametro è const aBody: string e il JSON lo costruisci tu. Le poche che fanno riferimento a uno schema nominato ottengono invece una classe tipizzata.

273 warning, e vale la pena leggerli

La maggior parte riguarda la composizione senza una mappatura del discriminatore, dove la classe generata porta un membro per ogni ramo. Alcuni segnalano un $ref che il documento non risolve, altri un'operazione che dichiara due status di successo, di cui solo uno viene generato. Il generatore dice quale, invece di scegliere in silenzio.

Rate limit e token delle app li gestisci tu

Il client generato è un client HTTP fedele e nient'altro. Non mette in cache i valori ETag, non riprova sui 403 e non rinnova l'installation token di una GitHub App. Leggi ResponseCode, usa OnBeforeRequest per aggiungere un header di richiesta condizionale, e crea gli installation token con i metodi apps che la unit contiene già.

Dal blog

Parser OpenAPI Delphi

Come il reader gestisce specifiche reali, incluse le keyword di composizione che stanno dietro alla maggior parte dei warning.

Leggi il post →

Client + parser OpenAPI

Il post di accompagnamento che presenta il client generato e il reader su cui è costruito.

Leggi il post →

sgcOpenAPI 2026.6

Note di rilascio della versione attuale, con le opzioni del generatore e le novità del reader.

Leggi il post →
La scelta più conveniente: All-AccessTutti i prodotti eSeGeCe, con Supporto Premium incluso, a partire da €1,059/anno.
Vedi i prezzi All-Access

Costruisci oggi la tua automazione GitHub

sgcOpenAPI include il reader, il code generator, il server OpenAPI e gli SDK già pronti per Amazon, Azure, Google e Microsoft. Un prodotto, tre tier, con prezzo a postazione invece che a funzionalità.