Cliente Delphi de la API REST de GitHub vía sgcOpenAPI

GitHub mantiene una de las descripciones OpenAPI más grandes que se publican en ninguna parte, y la distribuye bajo licencia MIT. sgcOpenAPI no incluye un componente de GitHub escrito a mano, incluye un generador. Una sola línea de comandos sobre api.github.com.json produce una única unit Pascal con 1.225 métodos, una clase de respuesta tipada para cada uno de ellos y una función GetOpenAPIClient que te entrega un cliente listo para usar.

GitHub + sgcOpenAPI

Las cifras que siguen se midieron ejecutando el generador sobre la descripción actual y compilando el resultado, no son estimaciones.

Spec de origen

descriptions/api.github.com/api.github.com.json en github/rest-api-description, declarada como OpenAPI 3.0.3. No hace falta ningún paso de conversión.

Lo que sale

813 paths se convierten en 1.225 métodos y 1.134 clases de respuesta, junto a 3.250 clases de modelo, en una sola unit de unas 274.000 líneas.

Autenticación

Genera con -a 2 y asigna Authentication.Token.BearerToken en tiempo de ejecución. Eso vale igual para un personal access token que para un installation token.

Compila

La unit generada compila limpia en RAD Studio 12 para Win32 sin nada en la ruta de librerías salvo la carpeta Source de sgcOpenAPI.

Ejecuta el generador

GitHub publica varias variantes de la misma descripción. api.github.com.json describe el servicio alojado y ghes-3.x.json describe GitHub Enterprise Server. Genera desde la que vayas a usar.

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

File successfully created github.pas

-i acepta un archivo local o una URL, en JSON o en YAML. -o es la unit Pascal que se escribe, y la unit toma el nombre de ese archivo. -a 2 selecciona la autenticación por token, así que cada método generado envía Authorization: Bearer. El mismo ejecutable es un asistente gráfico cuando se arranca sin parámetros, y sale con 0 si todo va bien, con 5 si el archivo de entrada es incorrecto, con 6 si lo es el de salida y con 7 cuando el documento no se puede convertir en un documento OpenAPI 3 válido.

Añade el .pas generado a tu proyecto y ponlo en una cláusula uses. No hay ningún componente que instalar, porque sgcOpenAPI no registra ninguno y no incluye paquete de diseño.

Lista tus repositorios

GitHub escribe sus operation ids con barras y guiones, como en repos/list-for-authenticated-user. Esos caracteres no pueden aparecer en un identificador Pascal, así que el generador los quita y el método llega como reposlistforauthenticateduser.

uses
  github;   // la unit que acabas de generar

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 que devuelve un array da una respuesta cuyo Successful es un descendiente de TsgcOpenAPIArray con un Items tipado, aquí TArray<TsgcOpenAPI_repository_Class>. La URL base sale de la entrada servers, así que el constructor generado ya establece https://api.github.com. La paginación no se te oculta: aPer_page y aPage son argumentos normales y recorres las páginas tú mismo.

Si los nombres en minúscula te molestan, genera con -m 1 y los métodos se nombran a partir del summary de la operación, o con -m 2 para nombrarlos a partir del endpoint.

Crea una issue y lista pull requests

Los parámetros de ruta llegan como argumentos iniciales, en el orden en que los declara el documento. El cuerpo de la petición llega como una cadena, por el motivo que se explica más abajo.

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 clase de respuesta lleva Successful más una propiedad por cada código de estado que declara el documento, así que Error304, Error401, Error403 y Error422 están ahí para leerlos cuando la llamada falla. Un estado que GitHub describe con un esquema con nombre se convierte en una clase, y uno que describe sin nada se convierte en una cadena simple. La propiedad de error se crea bajo demanda, así que nunca es nil y compruebas IsSuccessful en lugar de comprobar el objeto.

El guion bajo de _message no es una errata. message es una de las 68 palabras reservadas de Pascal que el generador escapa, así que un campo de esquema con ese nombre llega con un guion bajo delante. Lo mismo le pasa a type, object, default, index y al resto de la lista, y todas ellas aparecen en algún punto de los esquemas de GitHub.

Qué contiene la unit generada

La unit refleja la descripción. No hay nada seleccionado a mano, así que todo lo que GitHub documenta está presente y todo lo que GitHub omite no lo está.

Todas las operaciones documentadas

1.225 métodos, que cubren repositorios y contenidos, issues y pull requests, Actions y check runs, packages, organizaciones y equipos, GitHub Apps, code scanning y el resto de la superficie.

Una clase de respuesta por método

Cada una desciende de TsgcOpenAPIResponse y hereda IsSuccessful, que es cierto de 200 a 299, junto con ResponseCode y ResponseError.

3.250 clases de modelo

TsgcOpenAPI_repository_Class, TsgcOpenAPI_issue_Class, TsgcOpenAPI_basic_error_Class, TsgcOpenAPI_validation_error_Class y todos los demás esquemas de la sección components.

Los tags como comentarios

Los tags de GitHub se emiten como comentarios que agrupan los métodos dentro de la única clase cliente. No se convierten en clases separadas, así que todo cuelga de GetOpenAPIClient.

La documentación de la spec

Las descripciones propias de GitHub llegan como comentarios Pascal encima de cada método y cada propiedad, así que el IDE te las muestra donde las usas.

También Enterprise Server

Las descripciones ghes-3.x se generan igual. Mantén una unit generada por destino si hablas con los dos.

Cuatro cosas que conviene saber

Las cuatro salieron de una ejecución real del generador sobre la descripción actual.

La unit es muy grande

Unas 274.000 líneas y 12 MB, la mayor de las especificaciones públicas que generamos aquí. Compila en menos de dos segundos, pero el editor del IDE va lento con un archivo de ese tamaño. -x descarta las operaciones que listes como "VERB endpoint" y -p elimina después las clases que ya no usa ninguna operación.

La mayoría de los cuerpos de petición son cadenas

343 operaciones declaran un cuerpo application/json, pero casi todas lo describen como un objeto anónimo en línea y no como un esquema con nombre. Un objeto en línea no tiene clase a la que dar nombre, así que el parámetro es const aBody: string y el JSON lo construyes tú. Las pocas que referencian un esquema con nombre sí reciben una clase tipada.

273 avisos, y merece la pena leerlos

La mayoría hablan de composición sin mapeo de discriminador, donde la clase generada lleva un miembro por rama. Unos pocos informan de un $ref que el documento no resuelve, y unos pocos de una operación que declara dos estados correctos, de los cuales solo se genera uno. El generador dice cuál en lugar de elegir en silencio.

Los rate limits y los tokens de app son cosa tuya

El cliente generado es un cliente HTTP fiel y nada más. No cachea valores de ETag, no reintenta ante un 403 ni refresca el installation token de una GitHub App. Lee ResponseCode, usa OnBeforeRequest para añadir una cabecera de petición condicional, y emite installation tokens con los métodos apps que la unit ya contiene.

Desde el blog

Parser OpenAPI Delphi

Cómo el lector maneja especificaciones reales, incluidas las palabras clave de composición que están detrás de la mayoría de los avisos.

Leer post →

Cliente OpenAPI + parser

El post complementario que presenta el cliente generado y el lector sobre el que se apoya.

Leer post →

sgcOpenAPI 2026.6

Notas de la versión actual, con las opciones del generador y los cambios del lector.

Leer post →
La mejor opción: All-AccessTodos los productos de eSeGeCe, con Premium Support incluido, desde €1,059 al año.
Ver precios de All-Access

Construye tu automatización de GitHub hoy

sgcOpenAPI incluye el lector, el generador de código, el servidor OpenAPI y los SDK ya construidos de Amazon, Azure, Google y Microsoft. Un producto, tres niveles, con precio por puesto y no por funcionalidad.