Cliente Delphi para a REST API do GitHub via sgcOpenAPI

O GitHub mantém uma das maiores descrições OpenAPI publicadas em qualquer lugar, e a distribui sob a licença MIT. O sgcOpenAPI não entrega um componente GitHub escrito à mão, ele entrega um gerador. Uma única linha de comando sobre o api.github.com.json produz uma única unit Pascal com 1.225 métodos, uma classe de resposta tipada para cada um deles e uma função GetOpenAPIClient que devolve um cliente pronto.

GitHub + sgcOpenAPI

Os números abaixo foram medidos rodando o gerador sobre a descrição atual e compilando o resultado, não foram estimados.

Spec de origem

descriptions/api.github.com/api.github.com.json em github/rest-api-description, declarado como OpenAPI 3.0.3. Nenhuma etapa de conversão é necessária.

O que sai

813 paths viram 1.225 métodos e 1.134 classes de resposta, junto com 3.250 classes de modelo, em uma única unit de cerca de 274.000 linhas.

Autenticação

Gere com -a 2 e defina Authentication.Token.BearerToken em tempo de execução. Isso cobre tanto um personal access token quanto um installation token.

Compila

A unit gerada compila limpa no RAD Studio 12 para Win32 sem nada no library path além da pasta Source do sgcOpenAPI.

Rode o gerador

O GitHub publica várias variantes da mesma descrição. O api.github.com.json descreve o serviço hospedado e o ghes-3.x.json descreve o GitHub Enterprise Server. Gere a partir daquela que você usa.

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

File successfully created github.pas

-i aceita um arquivo local ou uma URL, em JSON e em YAML. -o é a unit Pascal a gravar, e a unit recebe o nome desse arquivo. -a 2 seleciona a autenticação por token, então todo método gerado envia Authorization: Bearer. O mesmo executável é um assistente gráfico quando iniciado sem parâmetros, e sai com 0 em caso de sucesso, 5 com um arquivo de entrada ruim, 6 com um arquivo de saída ruim e 7 quando o documento não pode ser transformado em um documento OpenAPI 3 válido.

Adicione o .pas gerado ao seu projeto e coloque-o em uma cláusula uses. Não há componente para instalar, porque o sgcOpenAPI não registra nenhum e não entrega pacote de design-time.

Liste os seus repositórios

O GitHub escreve os seus operation ids com barras e hífens, como em repos/list-for-authenticated-user. Esses caracteres não podem aparecer em um identificador Pascal, então o gerador os remove e o método chega como reposlistforauthenticateduser.

uses
  github;   // a unit que você acabou de gerar

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;

Um endpoint que devolve um array recebe uma resposta cujo Successful é um descendente de TsgcOpenAPIArray com um Items tipado, aqui TArray<TsgcOpenAPI_repository_Class>. A URL base sai da entrada servers, então o construtor gerado já define https://api.github.com. A paginação não é escondida de você: aPer_page e aPage são argumentos comuns e você percorre as páginas por conta própria.

Se os nomes em minúsculas te incomodam, gere com -m 1 e os métodos passam a ser nomeados a partir do summary da operação, ou com -m 2 para nomeá-los a partir do endpoint.

Crie uma issue e liste pull requests

Os parâmetros de path chegam como argumentos iniciais, na ordem em que o documento os declara. O corpo da requisição chega como string, pelo motivo explicado abaixo.

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;

Cada classe de resposta carrega Successful mais uma propriedade por código de status que o documento declara, então Error304, Error401, Error403 e Error422 estão lá para serem lidos quando a chamada falha. Um status que o GitHub descreve com um schema nomeado vira uma classe, e um que ele descreve com nada vira uma string comum. A propriedade de erro é criada sob demanda, então ela nunca é nil e você testa IsSuccessful em vez de testar o objeto.

O underscore em _message não é erro de digitação. message é uma das 68 palavras reservadas do Pascal que o gerador escapa, então um campo de schema com esse nome chega com um underscore inicial. O mesmo acontece com type, object, default, index e o resto da lista, todas elas presentes em algum ponto dos schemas do GitHub.

O que a unit gerada contém

A unit espelha a descrição. Nada é curado, então tudo o que o GitHub documenta está presente e tudo o que o GitHub deixa de fora não está.

Toda operação documentada

1.225 métodos, cobrindo repositórios e conteúdos, issues e pull requests, Actions e check runs, packages, organizações e times, GitHub Apps, code scanning e o resto da superfície.

Uma classe de resposta por método

Cada uma descende de TsgcOpenAPIResponse e herda IsSuccessful, que é verdadeiro para 200 a 299, além de ResponseCode e ResponseError.

3.250 classes de modelo

TsgcOpenAPI_repository_Class, TsgcOpenAPI_issue_Class, TsgcOpenAPI_basic_error_Class, TsgcOpenAPI_validation_error_Class e todo outro schema da seção components.

Tags como comentários

As tags do GitHub são emitidas como comentários que agrupam os métodos dentro da classe de cliente única. Elas não viram classes separadas, então tudo pende do GetOpenAPIClient.

A documentação da spec

As descrições do próprio GitHub vêm como comentários Pascal acima de cada método e de cada propriedade, então a IDE as mostra onde você as usa.

O Enterprise Server também

As descrições ghes-3.x são geradas da mesma forma. Mantenha uma unit gerada por alvo se você conversa com os dois.

Quatro coisas que vale a pena saber

As quatro saíram de uma geração real sobre a descrição atual.

A unit é muito grande

Cerca de 274.000 linhas e 12 MB, a maior das especificações públicas que geramos aqui. Ela compila em menos de dois segundos, mas o editor da IDE fica lento com um arquivo desse tamanho. O -x descarta as operações que você lista como "VERB endpoint" e o -p em seguida remove as classes que nenhuma operação restante usa.

A maioria dos corpos de requisição é string

343 operações declaram um corpo application/json, mas quase todas o descrevem como um objeto inline anônimo em vez de um schema nomeado. Um objeto inline não tem classe a nomear, então o parâmetro é const aBody: string e você monta o JSON. As poucas que referenciam um schema nomeado recebem uma classe tipada.

273 avisos, e vale a pena lê-los

A maioria é sobre composição sem um mapeamento de discriminator, onde a classe gerada carrega um membro por ramo. Alguns reportam um $ref que o documento não resolve, e alguns reportam uma operação que declara dois status de sucesso, dos quais apenas um é gerado. O gerador diz qual em vez de escolher em silêncio.

Rate limits e tokens de app ficam por sua conta

O cliente gerado é um cliente HTTP fiel e nada mais. Ele não guarda valores de ETag em cache, não repete a chamada em um 403 e não renova o installation token de um GitHub App. Leia ResponseCode, use OnBeforeRequest para adicionar um cabeçalho de requisição condicional, e emita installation tokens com os métodos apps que a unit já contém.

Do blog

Parser OpenAPI Delphi

Como o leitor lida com especificações reais, incluindo as palavras-chave de composição por trás da maior parte dos avisos.

Leia o post →

Cliente e parser OpenAPI

O post companheiro que apresenta o cliente gerado e o leitor sobre o qual ele é construído.

Leia o post →

sgcOpenAPI 2026.6

Release notes da versão atual, com as opções do gerador e as mudanças do leitor.

Leia o post →
Melhor custo-benefício: All-AccessTodos os produtos da eSeGeCe, com Suporte Premium incluído, a partir de €1,059/ano.
Ver preços do All-Access

Construa sua automação do GitHub hoje

O sgcOpenAPI entrega o leitor, o gerador de código, o servidor OpenAPI e SDKs pré-compilados para Amazon, Azure, Google e Microsoft. Um produto, três tiers, com preço por assento em vez de por recurso.