API discovery: OpenAPI without the bloat

Because Tiger's /api is a message pattern — the target module/service/method travels in the request, not the URL — the gateway already knows your entire API surface. So discovery isn't a bolt-on you maintain by hand; it's generated from the code you already wrote.

The spec, generated from your code

GET /api/openapi   →   a full OpenAPI 3 document

Tiger_OpenApi_Generator reflects every @api service and its public methods into operations, and it does something most OpenAPI setups can't: it reads your request schemas straight from your Forms. A Tiger_Form's elements() already declares the fields, types, and validators — that is the request body. Add one docblock tag to a service method and the schema comes for free:

/**
 * Create an invoice.
 * @apiRequest Billing_Form_Invoice
 */
public function create(array $params): void { … }

So: services → operations, docblocks → descriptions, Forms → request schemas, the response envelope → responses, the ACL → security. Almost nothing is hand-authored, and it can't drift from the code.

Verb-agnostic, one endpoint

/api ignores the HTTP verb (it reads params from $_GET + $_POST regardless), so each operation is described canonically as POST /api/{module}/{service}/{method} — browsable, "try it out"–able — and is equally callable as the primary message form (POST /api with {module, service, method, …}). One endpoint, any verb, params wherever they fit.

Opt-in

Discovery is off by default — a shared-host CMS install shouldn't publish its API surface. Turn it on when you're building a public or mobile API:

tiger.api.discovery = 1

Then GET /api/openapi returns the spec. (Discovery is designed to eventually be ACL-filtered — you only discover what your role can call — so the catalog never leaks an operation you can't invoke.)

The Swagger UI

Serving the spec is core; rendering it in Swagger UI is a separate, optional add-on — the TigerAPIDocs module. Install it and browse /apidocs for the interactive UI; without it (or on a locked-down host), /apidocs degrades to the raw JSON. See that module's own docs for the details — this page is just the platform's spec generation.

See also