cebe/php-openapi
Read and write OpenAPI 3.0.x YAML and JSON files as PHP objects, with a CLI tool for validating and converting descriptions. A low-level library used by higher-level API tooling.
Architecture fit. cebe/php-openapi is a low-level, framework-agnostic library, not an application-layer tool. Its value to a Laravel product is as an internal component in a contract-first pipeline: parse/lint an OpenAPI 3.0.x document, resolve $ref graphs (local, external, URL), and hand a typed object graph to whatever consumes it — CI validation, codegen, documentation publishing, or runtime request/response validation through league/openapi-psr7-validator (which itself depends on this package). The object model mirrors the specification one-to-one, so there is almost no abstraction to learn or fight. That makes it a good "plumbing" dependency and a poor choice as a user-facing integration: expect to wrap it in a domain service rather than call Reader directly from controllers.
Integration feasibility. High. composer require cebe/php-openapi, PHP 7.1+ with confirmed 8.2/8.3 support and Symfony 7 compatibility in 1.8.0. A viable spike is 1–3 engineer-days: read a real spec from resources/openapi, bind the parsed spec into the container as a singleton, expose a small facade. The CLI (validate, convert, inline) is usable as a CI step today with meaningful exit codes (2 = validation errors, 1 = other errors), which makes it adoptable without any application code at all.
Technical risk.
validate() is structural only; JSON Schema validation exists only in the CLI; Schema object validation is unimplemented and "passing doesn't mean valid." Do not let a green PHP validation call become the quality gate — the CLI must be the gate.../ segments, plus behavior fixes for referenced parameters compiling to arrays. Spec composition across files is where incidents will originate.RESOLVE_MODE_ALL expands the document with heavy repetition and truncates at recursive pointers — a memory and diff-noise hazard on large specs.hotmeteor/spectator). Trust the consumers, not the count, but do verify transitive version constraints before adoption.Key questions.
Writer) or is this read-only? Writing specs programmatically is verbose and rarely worth it versus generating from annotations/routes.Stack fit. Laravel 10/11/12 on PHP 8.2+ is a clean fit; there is no framework coupling to negotiate. Structure it as: a thin OpenApiServiceProvider binding a SpecRepository/ContractRegistry singleton, with parsing behind an interface so the parser can be swapped. Keep the library out of controllers and jobs' public signatures.
Migration path. Sequence from lowest-risk to highest:
validate (and inline for multi-file specs) as a CI job against the spec already in the repo. Zero runtime risk, immediate value.Compatibility. This is complementary to, not a replacement for, dedoc/scramble or darkaonline/l5-swagger: those emit a spec, this consumes and validates it. Avoid running two spec sources — pick one generator, then validate its output with this package in CI. That resolves the common failure where a hand-maintained spec and an annotated one drift apart.
Sequencing. Pin an exact version in composer.json and commit the lock. Land the CI gate before any runtime integration; runtime integration before codegen. Each stage is independently revertible.
Maintenance. Low code volume, infrequent releases (last May 2025), MIT license, and a narrow, stable public API. Budget roughly 1–2 engineer-days per quarter for version bumps and spec hygiene, plus a small contingency for a fork if upstream goes dormant. Track the changelog for reference-resolution changes specifically.
Support. Community issues plus paid consulting/support from the author — a genuinely useful risk valve for a single-maintainer project. No SLA, so treat production runtime validation as a component that needs a documented kill switch (feature flag to bypass enforcement).
Scaling. Parsing and resolution are CPU- and memory-bound and scale poorly with spec size, especially under RESOLVE_MODE_ALL. The scaling answer is architectural: resolve and normalize at build/deploy time, cache the result, and never let per-request code touch a raw multi-file spec. Runtime validation adds per-request latency — restrict it to non-production, sampled, or high-risk routes. The CLI scales trivially in CI.
Failure modes to instrument.
$ref (especially multi-../ and cross-file JSON references) throwing at read time — fail the build, not the request.validate() returning true on an invalid spec.RESOLVE_MODE_ALL with large or recursive specs.Ramp-up. The library API is learnable in hours for anyone fluent in OpenAPI 3.0; the real onboarding cost is specification literacy, not PHP. Assume 1–2 days to first productive contribution and invest in a short internal runbook covering: where the canonical spec lives, how to run validate locally, which resolve mode is sanctioned, and the caching contract. The README's examples (read, write, resolve, validate caveats) are adequate as a starting point and should be linked rather than duplicated.
How can I help you explore Laravel packages today?