macpaw/behat-openapi-psr7-validator
Behat extension for validating PSR-7 HTTP requests and responses against OpenAPI specifications. Add schema-driven API contract checks to Behat scenarios with ready-to-use steps for request and response validation.
Architecture fit. Unchanged by v1.1.0. This is a Behat extension, not a Laravel package — it registers itself into Behat's extension lifecycle and delegates all validation to league/openapi-psr7-validator, which operates on PSR-7 RequestInterface/ResponseInterface pairs. Laravel's native testing stack (PHPUnit/Pest plus Illuminate\Testing\TestResponse) does not speak PSR-7, so the package sits orthogonal to the framework: it creates a parallel BDD/contract-testing lane rather than integrating into Laravel's service container. That is acceptable if framed as black-box contract testing; it is a poor fit if the goal is to validate in-process feature tests.
Integration feasibility. Moderate, and marginally improved. Three things must exist: a Behat harness (behat/behat plus behat.yml), an OpenAPI 3.x spec, and a way to produce PSR-7 message pairs. Two viable paths:
FeatureContext calls a running app through a PSR-18 client and hands PSR-7 responses to the extension. Lowest friction, highest fidelity, but requires a running environment in CI.TestResponse to PSR-7 (e.g., symfony/psr-http-message-bridge or a custom adapter). Cheaper to run, but conversion can silently drop streamed bodies, binary payloads, and some headers, producing false results.v1.1.0 widens dependency constraints to pick up the latest packages, which directly reduces the odds of the collision risk flagged in the prior assessment (Behat's Symfony constraints vs. the Laravel version in use, and PSR-7 implementation pinning). Treat this as headroom, not a guarantee: widening is not the same as testing against the full matrix, so pin-and-verify remains the operating rule.
Technical risk. The validation engine is credible and maintained; the glue is the risk. v1.1.0 does not change the fundamentals: still one star, zero dependents, single-vendor provenance (MacPaw), and a contributor base that in practice is one person (zakhar-huzenko authored all three PRs in this release). Bus factor ≈ 1 stands.
Two mild positive signals in this release: a PHPStan error was fixed, which implies static analysis runs somewhere in the project's CI (quality hygiene above what a one-star package usually shows); and an AGENTS.md was added, indicating AI-assisted contribution is now an explicit, documented workflow. The latter is neutral-to-slightly-negative for review confidence — it lowers the cost of maintenance but also means code review depth should be verified rather than assumed. Because the surface is thin, a fork is cheap under MIT — but that contingency should be planned, not discovered.
The larger risk remains validation theater: if the OpenAPI spec is auto-generated from the same Laravel routes/controllers it validates, the tests assert tautologies and will not catch contract drift.
Confirmed from the changelog: v1.1.0 contains no breaking changes, no new validation features, no deprecations. It is a hygiene-and-compatibility release. Nothing in the prior evaluation's caveats is retired.
Key questions.
Stack fit. Target Laravel 10–12 on PHP 8.1+. Behat should coexist with Pest, not replace it: keep unit/integration tests in Pest, add a narrow contract-testing lane in Behat. Isolate it behind a dedicated composer script (e.g., composer bdd) and a separate CI job so the main suite's speed is untouched. v1.1.0's widened constraints make this integration easier to land on current stacks, but the isolation still matters more than the constraint range — a permissive constraint that pulls in an untested transitive version is a slow-motion break.
Migration path. Do not retrofit the whole API. Select 3–5 stable, high-value endpoints where contract drift is expensive — authentication, payments, webhooks — and start there. Establish the spec as a reviewed artifact first: generate a draft with Scramble or Scribe if useful, but hand-review and commit it as the source of truth rather than regenerating it in CI. Then add the harness and a single FeatureContext that performs real HTTP calls.
Compatibility. Pin league/openapi-psr7-validator to a version satisfying the extension's constraint. Reuse a PSR-7 implementation already in the dependency tree (nyholm/psr7 or guzzlehttp/psr7) to avoid interface duplication. v1.1.0 widened the dependency ranges, so the immediate action is to re-resolve and re-lock rather than assume the previous pins still apply — run a full composer update --dry-run against the target Laravel version and confirm no Symfony or PSR interface duplication appears. Ensure the Behat-run environment and base URL match the deployed configuration under test.
Sequencing.
Maintenance. Pin exact versions and vendor or fork on abandonment — the MIT license and thin surface make a fork a one-to-two-day task. Budget roughly one to two days per quarter for upgrades plus ongoing spec upkeep, which will exceed the cost of the package itself. v1.1.0 is a low-cost upgrade on its own (a PHPStan fix plus constraint widening), but the release cadence — sporadic, maintenance-only, no roadmap — confirms this should be tracked as vendored internal tooling with a version bump every few months, not as a dependency you expect to keep pace with the ecosystem.
Support. Community-only, no SLA, low issue traffic. Ownership must be explicit internally — typically a QA or platform engineer — and the harness should be documented as internal tooling rather than treated as a vendor-supported dependency. The addition of AGENTS.md in v1.1.0 is a signal worth noting to reviewers: contribution is now partly automated, so internal review of upgrade diffs remains necessary even for small releases.
Scaling. Validation is CPU- and I/O-bound per scenario, and cost grows with scenario count and payload size; the validator materializes full message bodies, so memory limits matter for large responses. Run in a dedicated CI job, shard by tag, and cache Composer artifacts. Black-box mode also adds environment provisioning cost and flakiness relative to in-process tests.
Failure modes.
example/format handling.Establish a triage taxonomy — spec bug, implementation bug, harness bug — before scaling coverage.
Ramp-up. Laravel developers fluent in Pest need onboarding on Gherkin and Behat (roughly one to two days) plus OpenAPI literacy. Amortize it by reusing step definitions across features and shipping a template feature file. Start with a single champion and a deliberately small first slice rather than a team-wide rollout.
How can I help you explore Laravel packages today?