diff --git a/readme.md b/readme.md index 1f6c6b2..531ce0e 100644 --- a/readme.md +++ b/readme.md @@ -24,6 +24,26 @@ composer require --dev gertjuhh/symfony-openapi-validator - The `operationAddress` can be passed as a third argument for this function but by default it will retrieve the operation from the `client`. +### Setting up a cache + +The [underlying library can use a PSR-6 cache](https://github.com/thephpleague/openapi-psr7-validator#caching-layer--psr-6-support). +This provides a significant speedup when running multiple tests against a single schema, since it can be parsed once and +reused. + +In order to activate this cache, you can pass a PSR-6 cache instance to the static property +`\Gertjuhh\SymfonyOpenapiValidator\StaticOpenApiValidatorCache::$validatorCache`. For example: + +```php + */ - private static array $validatorBuilder = []; - /** @throws AssertionFailedError */ public static function assertOpenApiSchema(string $schema, KernelBrowser $client): void { - $builder = self::getValidatorBuilder($schema); - $psrFactory = self::getPsrHttpFactory(); + $builder = StaticOpenApiValidatorCache::getValidatorBuilder($schema); + $psrFactory = StaticOpenApiValidatorCache::getPsrHttpFactory(); try { $match = $builder->getServerRequestValidator() @@ -42,8 +34,8 @@ public static function assertResponseAgainstOpenApiSchema( KernelBrowser $client, OperationAddress | null $operationAddress = null, ): void { - $builder = self::getValidatorBuilder($schema); - $psrFactory = self::getPsrHttpFactory(); + $builder = StaticOpenApiValidatorCache::getValidatorBuilder($schema); + $psrFactory = StaticOpenApiValidatorCache::getPsrHttpFactory(); if ($operationAddress === null) { $operationAddress = new OperationAddress( @@ -74,25 +66,6 @@ private static function extractPathFromException(\Throwable $exception): string return null; } - private static function getPsrHttpFactory(): PsrHttpFactory - { - if (null === self::$psrHttpFactory) { - $psr17Factory = new Psr17Factory(); - self::$psrHttpFactory = new PsrHttpFactory($psr17Factory, $psr17Factory, $psr17Factory, $psr17Factory); - } - - return self::$psrHttpFactory; - } - - private static function getValidatorBuilder(string $schema): ValidatorBuilder - { - if (!\array_key_exists($schema, self::$validatorBuilder)) { - self::$validatorBuilder[$schema] = (new ValidatorBuilder())->fromYamlFile($schema); - } - - return self::$validatorBuilder[$schema]; - } - private static function wrapValidationException(\Throwable $exception, string $scope): AssertionFailedError { $message = [$exception->getMessage()]; @@ -132,4 +105,3 @@ private static function wrapValidationException(\Throwable $exception, string $s ); } } - diff --git a/src/StaticOpenApiValidatorCache.php b/src/StaticOpenApiValidatorCache.php new file mode 100644 index 0000000..60e3038 --- /dev/null +++ b/src/StaticOpenApiValidatorCache.php @@ -0,0 +1,49 @@ + */ + private static array $validatorBuilder = []; + + /** + * Install a cache pool for the OpenAPI Validator + * + * @see https://github.com/thephpleague/openapi-psr7-validator#caching-layer--psr-6-support + */ + public static CacheItemPoolInterface|null $validatorCache = null; + + public static function getPsrHttpFactory(): PsrHttpFactory + { + if (null === self::$psrHttpFactory) { + $psr17Factory = new Psr17Factory(); + self::$psrHttpFactory = new PsrHttpFactory($psr17Factory, $psr17Factory, $psr17Factory, $psr17Factory); + } + + return self::$psrHttpFactory; + } + + public static function getValidatorBuilder(string $schema): ValidatorBuilder + { + if (!\array_key_exists($schema, self::$validatorBuilder)) { + self::$validatorBuilder[$schema] = (new ValidatorBuilder()) + ->fromYamlFile($schema); + + if (self::$validatorCache !== null) { + self::$validatorBuilder[$schema]->setCache(self::$validatorCache); + } + } + + return self::$validatorBuilder[$schema]; + } +}