- Is league/openapi-psr7-validator a Laravel package?
- No. It is a framework-agnostic PSR-7 library from The League with no service provider, config file, or facade, so any Laravel integration is your own construction. That is an architectural advantage because it stays portable to Slim, Laminas, Mezzio, and RoadRunner or Swoole stacks. It also means you inherit none of the usual Laravel package conveniences.
- How do I install league/openapi-psr7-validator in a Laravel project?
- Install it with composer require league/openapi-psr7-validator. Because Laravel's HTTP layer is Symfony-based rather than PSR-7, you will also need a bridge such as symfony/psr-http-message-bridge plus a PSR-7 implementation like nyholm/psr7 or guzzlehttp/psr7. There is no auto-discovery step or publishable configuration to run.
- How do I validate a Laravel request if Laravel does not use PSR-7?
- Convert the Illuminate request into a PSR-7 ServerRequestInterface using the Symfony PSR bridge, then pass that message to the validator. Put the conversion at the HTTP boundary, for example in a middleware or a test helper, rather than inside domain validators. The conversion has a per-request cost, so apply it deliberately instead of everywhere by default.
- Does it support OpenAPI 3.1 or should I look at alternatives?
- It targets OpenAPI 3.0.x only and parses the document through cebe/php-openapi. If your roadmap depends on 3.1 semantics such as JSON Schema 2020-12, nullable removal, or exclusiveMinimum changes, this package could become a blocker. Confirm your spec version before committing and evaluate alternatives if 3.1 is required.
- What is the difference between getServerRequestValidator and getRoutedRequestValidator?
- The server request validator matches an incoming message to an operation defined in the spec, which is convenient but slower because it has to route against the document. The routed validator takes an OperationAddress you supply from Laravel's router, which is faster and more predictable when the application already handles routing. Use the auto-matching validator mainly for contract tests.
- Can it validate responses as well as requests?
- Yes, but response validation is not automatic. You need to know the OperationAddress for the response and wire the response validator explicitly, such as in a base controller, a middleware wrapper, or a test helper. Requests are the easier half because the incoming message usually identifies the operation.
- How do I use it for API contract testing in PHPUnit or Pest?
- Build a validator once from your OpenAPI document with ValidatorBuilder, then assert that real requests and responses validate for a known OperationAddress. This is the natural home for the auto-matching server request validator. It catches transport-level drift such as headers, cookies, query arguments, path parameters, status codes, and bodies that domain tests usually ignore.
- What happens when validation fails inside a Laravel application?
- The library throws exceptions rather than returning responses, so it is fail-closed by default. Laravel's default exception rendering will surface those as 500 errors until you teach the handler to map ValidationFailed subclasses to 400, 415, or 422 with useful error bodies. Make sure those bodies do not leak specification internals.
- Can I load the spec from YAML or JSON, and can I cache parsing?
- Both formats are supported through fromYaml and fromYamlFile as well as fromJson and fromJsonFile, or you can pass a pre-built cebe openapi spec object. The validator exposes getSchema and supports PSR-6 caching, which helps avoid re-parsing the document on every call. Caching parsing does not remove the per-request cost of traversing the spec during validation.
- How do I register custom formats, and are there performance concerns?
- Custom formats are registered with FormatsContainer::registerFormat, which is process-global mutable state, so register once at boot and avoid per-tenant or per-team format differences. Performance is not free: auto-routing validation compiles and traverses the spec per request, and large specs with deep ref graphs plus the PSR-7 bridge can add measurable latency. A PSR-6 cache mitigates parsing but not validation traversal.