Skip to content

REST API OpenAPI Standards

Ed Mozley edited this page Jul 4, 2026 · 3 revisions

βœ… REST API: how the OpenAPI document is kept correct

This page describes how the OpenAPI document is generated, validated and verified. It is written for developers evaluating whether the specification can be trusted as a contract.


It is generated, not hand-written

The document is produced on each request by a generator that reads three sources already maintained as part of the API:

  • the route table β€” the authoritative list of paths, methods, permissions and handler functions the front controller dispatches;
  • the documentation catalogue β€” endpoint summaries, descriptions, parameters, request examples and endpoint-specific errors, shared with the interactive docs page;
  • the typed schemas β€” reusable component schemas describing every response object.

Because it is derived from the live route table, the specification describes the API the install is actually running. There is no separate file to fall out of date.


It conforms to the OpenAPI standard

The document validates against the official OpenAPI 3.0 meta-schema with zero errors. Conformance is verified two ways:

  • a bundled validator checks the generated document against a local copy of the official meta-schema (api/v1/dev/jsonschema4.php), so it can be re-run offline at any time;
  • the same document loads in Swagger UI, Redoc, Postman and Insomnia, and drives the client generators (openapi-generator, swagger-codegen).

The validator is proven to reject malformed documents β€” a document with a missing openapi version, a missing responses object, or an out-of-range version string all fail it β€” so a clean pass is a meaningful result rather than a validator that passes everything.

For teams that run linters in CI, the document passes Spectral's recommended ruleset and swagger-cli validate in a Node environment.


The response schemas match reality

Every response schema is validated against a live response from a running install. A verification tool (api/v1/dev/openapi_verify.php) fetches each GET endpoint, resolves any id parameters from a sibling collection, and checks the returned data against its schema field-by-field β€” including type and nullability, and flagging any response field the schema fails to document. The schemas were derived from the serializers and then reconciled against live data until this reported zero mismatches.

The types are read directly from the serializers, which cast every value explicitly ((int), (bool), dates through a shared ISO-8601 helper, nested objects, arrays), so the declared types reflect what the code emits rather than an inference from a single sample.


The specification cannot silently omit or invent an endpoint

A self-check (api/v1/lib/openapi_check.php) verifies a set of invariants and exits non-zero on any failure, so it can gate CI:

  • drift β€” every route in the table has a specification entry and every specification entry maps to a real route (a clean one-to-one match);
  • references β€” every $ref resolves to a defined component schema;
  • operationIds β€” present and unique across all operations;
  • responses β€” every operation declares at least one response;
  • shape β€” no object-typed field is emitted as an empty array.

Scope and format choices

  • Version 3.0.3. Targeted for the widest tooling compatibility. It imports into current and older Swagger UI, Redoc, Postman, Insomnia and the mainstream client generators.
  • Two formats, one document. JSON is canonical; YAML is generated from the same structure with conservative quoting, so scalars are never coerced to the wrong type.
  • Dynamic payloads are typed as open objects. Workflow conditions and actions, form field definitions, and workflow-execution payloads and step logs vary in shape by design; they are described as objects rather than given a fixed field list that would misrepresent them.
  • Request bodies are documented with worked examples. The API validates request fields at call time; response bodies additionally carry full typed schemas. A small number of endpoints that require a specific nested id are covered by their derived schema but are not part of the automated live-verification sweep.

Re-running the checks

The tooling needs only PHP β€” no Node, Python or Composer:

# invariants (drift, refs, operationIds, responses, shape)
php api/v1/lib/openapi_check.php

# conformance to the official 3.0 meta-schema
curl -s http://localhost/freeitsm-app/api/v1/openapi.json > /tmp/o.json
php api/v1/dev/jsonschema4.php /tmp/o.json api/v1/dev/oas-3.0-schema.json

# response schemas vs live responses (needs a read key)
php api/v1/dev/openapi_verify.php <read_key>

See api/v1/dev/README.md for the full workflow, including how to bring the typed schemas back in line after changing a module.

See also: REST API: OpenAPI specification (getting and using it) Β· REST API (how the API works).

FreeITSM

Getting Started

Modules

Multi-tenancy (planned)

Blue sky thinking

Bugs resolved

Links

Clone this wiki locally