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
- Webservices: the
/apipattern — how the message endpoint works. - API tokens — authenticating a stateless API client.