diff --git a/README.md b/README.md index bb4441fc..300eb659 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,8 @@ Validation of `\Psr\Http\Message\ResponseInterface` is a bit more complicated . Because you need not only YAML file and Response itself, but also you need to know which operation this response belongs to (in terms of OpenAPI). +Reponse validation is optional and is enabled by default. See [Skipping response validation](#skipping-response-validation) + Example: ```php @@ -194,6 +196,15 @@ You can use `->setCache($pool, $ttl)` call for both PSR-7 and PSR-15 builder in If you want take control over the cache key for schema item, or your cache does not support cache key generation by itself you can `->overrideCacheKey('my_custom_key')` to ensure cache uses key you want. +### Skipping response validation +If you want to skip response validation and only validate requests, you can call `->shouldValidateResponse(false)` method on the builder like this: +```php +$psr15Middleware = (new \OpenAPIValidation\PSR15\ValidationMiddlewareBuilder) + ->fromYamlFile($yamlFile) + ->shouldValidateResponse(false) + ->getValidationMiddleware(); +``` + ### Standalone OpenAPI Validator The package contains a standalone validator which can validate any data against an OpenAPI schema like this: diff --git a/src/PSR15/ValidationMiddleware.php b/src/PSR15/ValidationMiddleware.php index e153498b..7a4f2893 100644 --- a/src/PSR15/ValidationMiddleware.php +++ b/src/PSR15/ValidationMiddleware.php @@ -18,10 +18,10 @@ final class ValidationMiddleware implements MiddlewareInterface { /** @var ServerRequestValidator */ private $requestValidator; - /** @var ResponseValidator */ + /** @var ResponseValidator|null */ private $responseValidator; - public function __construct(ServerRequestValidator $requestValidator, ResponseValidator $responseValidator) + public function __construct(ServerRequestValidator $requestValidator, ?ResponseValidator $responseValidator = null) { $this->requestValidator = $requestValidator; $this->responseValidator = $responseValidator; @@ -46,11 +46,13 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface // 2. Process request $response = $handler->handle($request); - // 3. Validate response - try { - $this->responseValidator->validate($matchedOASOperation, $response); - } catch (ValidationFailed $e) { - throw InvalidResponseMessage::because($e); + if ($this->responseValidator !== null) { + // 3. Validate response + try { + $this->responseValidator->validate($matchedOASOperation, $response); + } catch (ValidationFailed $e) { + throw InvalidResponseMessage::because($e); + } } return $response; diff --git a/src/PSR15/ValidationMiddlewareBuilder.php b/src/PSR15/ValidationMiddlewareBuilder.php index 99183bf6..70cc14cc 100644 --- a/src/PSR15/ValidationMiddlewareBuilder.php +++ b/src/PSR15/ValidationMiddlewareBuilder.php @@ -9,11 +9,24 @@ class ValidationMiddlewareBuilder extends ValidatorBuilder { + /** @var bool */ + protected $shouldValidateResponse = true; + + /** + * @return $this + */ + public function shouldValidateResponse(bool $value): self + { + $this->shouldValidateResponse = $value; + + return $this; + } + public function getValidationMiddleware(): MiddlewareInterface { return new ValidationMiddleware( $this->getServerRequestValidator(), - $this->getResponseValidator() + $this->shouldValidateResponse ? $this->getResponseValidator() : null ); } } diff --git a/tests/PSR15/ValidationMiddlewareTest.php b/tests/PSR15/ValidationMiddlewareTest.php index dc18cd41..08fd30a1 100644 --- a/tests/PSR15/ValidationMiddlewareTest.php +++ b/tests/PSR15/ValidationMiddlewareTest.php @@ -59,4 +59,24 @@ public function testItReturnsExpectedException( $this->expectException($expectedExceptionType); $middleware->process($serverRequest, $handler); } + + public function testItDoesNotValidateResponseIfNoValidatorConfigured(): void + { + $this->expectNotToPerformAssertions(); + + $builder = (new ValidatorBuilder())->fromYamlFile($this->apiSpecFile); + + $middleware = new ValidationMiddleware( + $builder->getServerRequestValidator(), + null + ); + + $handler = $this->createMock(RequestHandlerInterface::class); + $handler + ->method('handle') + ->willReturn(new Response()); + + // no exception thrown + $middleware->process($this->makeGoodServerRequest('/read', 'get'), $handler); + } }