OpenAPI 3 & Swagger
MARS can generate an OpenAPI 3 specification for an application directly from your resources — no hand-written YAML. It reflects over the registered resources, methods, parameters, return types and authorization rules to build a TOpenAPI document (MARS.OpenAPI.v3.pas), which you expose as JSON or YAML and render with Swagger UI.
How it works
- Add
MARS.OpenAPI.v3.InjectionServiceto your ignitionuses. This registers an injection service that builds aTOpenAPIfor the current application on demand. - Declare a resource whose method takes
[Context] AOpenAPI: TOpenAPIand returns it. MARS serializes it to JSON/YAML. - Optionally serve the Swagger UI static files from a folder.
Internally, TOpenAPIHelper.BuildFrom(engine, application) drives a TMARSMetadataReader (see Metadata) to enumerate everything and fills the OpenAPI object — including server URLs, the application path, and security schemes for JWT (Bearer and/or cookie) when the app has a JWT secret configured.
Exposing the spec
This is the canonical resource from the MARSTemplate demo:
unit Server.Resources.OpenAPI;
interface
uses
MARS.Core.Attributes, MARS.Core.MediaType, MARS.Core.JSON
, MARS.WebServer.Resources
, MARS.OpenAPI.v3, MARS.Metadata.Attributes;
type
[Path('openapi'), MetaVisible(False), JSONSkipEmptyValues]
TOpenAPIResource = class
public
[GET, Produces(TMediaType.APPLICATION_JSON), Produces(TMediaType.APPLICATION_YAML)]
function GetOpenAPI([Context] AOpenAPI: TOpenAPI): TOpenAPI;
end;
[Path('www/{*}'),
RootFolder('{bin}\..\..\..\www\swagger-ui-3.52.5-dist', True), MetaVisible(False)]
TStaticContentResource = class(TFileSystemResource)
end;
implementation
uses MARS.Core.Registry;
function TOpenAPIResource.GetOpenAPI(AOpenAPI: TOpenAPI): TOpenAPI;
begin
Result := AOpenAPI; // injected & fully built for this application
end;
initialization
MARSRegister([TOpenAPIResource, TStaticContentResource]);
end.Notes:
[MetaVisible(False)]keeps these helper resources out of the generated spec itself.[JSONSkipEmptyValues]produces a clean document without empty members.GET …/openapireturns the spec; anAccept: application/yamlheader (withMARS.YAML.ReadersAndWritersregistered) returns YAML instead.TStaticContentResourceserves the bundled Swagger UI from the repository'swww/swagger-ui-*folder viaTFileSystemResource+[RootFolder].
Endpoints (under application /default):
GET /rest/default/openapi → OpenAPI 3 JSON (or YAML)
GET /rest/default/www/ → Swagger UI, pointed at the specEnriching the spec
The generator reads metadata and JSON-schema attributes so you can produce a rich, accurate document:
- Summaries / descriptions —
[MetaSummary('...')],[MetaDescription('...')]on resources, methods and parameters. - Visibility —
[MetaVisible(False)]hides a resource or method. - Schema hints on record/class fields —
[OAPIDescription],[OAPIRequired],[OAPIPattern],[OAPIMinimum],[OAPIMaximum]. - Security —
[RolesAllowed]/[PermitAll]/[DenyAll]are reflected as security requirements; when JWT is configured, Bearer and cookie security schemes are added automatically.
[Path('users')]
[MetaSummary('User management')]
[MetaDescription('Create, list and remove application users')]
[RolesAllowed('admin')]
TUserResource = class
public
[GET]
[MetaSummary('List users')]
function List: TArray<TUser>;
[POST]
[MetaSummary('Create user')]
function Create([BodyParam] AUser: TUser): TUser;
end;Parameter kinds ([PathParam], [QueryParam], [HeaderParam], [BodyParam]) and their Delphi types become the corresponding OpenAPI parameters, request bodies and schemas.
Metadata
OpenAPI generation is built on a general metadata layer (MARS.Metadata.*) that models your API as a tree of TMARSApplicationMetadata → TMARSResourceMetadata → TMARSMethodMetadata → TMARSRequestParamMetadata. TMARSMetadataReader populates it by RTTI reflection over the engine's applications.
You can use this metadata directly for your own tooling — for instance, the HtmxDemo reads the generated OpenAPI document at runtime to render a live list of endpoints in an HTML page.
Consuming the spec
Because the document is standard OpenAPI 3, you can feed …/openapi into any compatible tool: Swagger UI (bundled), Postman, client-code generators, or API gateways.
