Description
This package can validate PSR-7 messages against OpenAPI (3.0.x) specifications expressed in YAML or JSON.
OpenAPI PSR-7 Message (HTTP Request/Response) Validator alternatives and similar libraries
Based on the "Frameworks" category.
Alternatively, view OpenAPI PSR-7 Message (HTTP Request/Response) Validator alternatives based on common mentions on social networks and blogs.
-
Laravel 5
Laravel is a web application framework with expressive, elegant syntax. We’ve already laid the foundation for your next big idea — freeing you to create without sweating the small things. -
CodeIgniter
Open Source PHP Framework (originally from EllisLab) -
Symfony
The Symfony PHP framework -
Yii2
Yii 2: The Fast, Secure and Professional PHP Framework -
Swoole
🚀 Coroutine-based concurrency library for PHP -
CakePHP
CakePHP: The Rapid Development Framework for PHP - Official Repository -
Phalcon
High performance, full-stack PHP framework delivered as a C extension. -
Slim Framework
Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs. -
Zend Framework 2
Another framework comprised of individual components (ZF2). -
CodeIgniter 4 Development
Open Source PHP Framework (originally from EllisLab) -
swoft
🚀 PHP Microservice Full Coroutine Framework -
FuelPHP
Fuel PHP Framework v1.x is a simple, flexible, community driven PHP 5.3+ framework, based on the best ideas of other frameworks, with a fresh start! FuelPHP is now fully PHP 8.0 compatible. -
Spiral Framework
High-Performance PHP Framework -
Kraken PHP
Asynchronous & Fault-tolerant PHP Framework for Distributed Applications. -
MopaBootstrapBundle
Easy integration of twitters bootstrap into symfony2 -
Opulence
A simple, secure, and scalable PHP application framework -
Ubiquity
Ubiquity framework -
Nette
📖 The Nette documentation -
ATK UI
Robust and easy to use PHP Framework for Web Apps -
Swiftlet
Quite possibly the smallest MVC framework you'll ever use. -
KumbiaPHP
Fast and easy PHP framework -
Aura PHP
Dependency Injection System -
Ice
Source code of Ice framework -
Redaxscript
A modern, ultra lightweight and rocket fast Content Management System -
PHP-Spellchecker
🐘🎓📝 PHP Library providing an easy way to spellcheck multiple sources of text by many spellcheckers -
PHP-GLFW
🪐A fully-featured OpenGL and GLFW extension for PHP. 🔋Batteries included (Math Functions, Texture Loaders, etc..) -
PPI Framework 2
The PPI Framework Engine -
CleverStyle Framework
Simple, scalable, fast and secure full-stack PHP framework -
Equip
A tiny, yet powerful, PHP micro-framework. -
php-speller
PHP spell check library -
Quantum PHP Framework (project)
Quantum PHP Project -
Radar
The Action-Domain-Responder core for Radar. -
Quantum PHP Framework (core)
Quantum PHP Framework -
Mako Framework
Mako skeleton application. -
ReactPHP Promises Testing
PHPUnit assertions for testing ReactPHP promises -
Slim3 GAE Skeleton
Slim 3 skeleton working with Google App Engine include cron configuration. -
Symfony 3
A framework comprised of individual components (SF3). -
Aura Framework
A framework built from independent components.
Clean code begins in your IDE with SonarLint
* Code Quality Rankings and insights are calculated and provided by Lumnify.
They vary from L1 to L5 with "L5" being the highest.
Do you think we are missing an alternative of OpenAPI PSR-7 Message (HTTP Request/Response) Validator or a related project?
Popular Comparisons
-
OpenAPI PSR-7 Message (HTTP Request/Response) ValidatorvsLaravel 5
-
OpenAPI PSR-7 Message (HTTP Request/Response) ValidatorvsCleverStyle Framework
-
OpenAPI PSR-7 Message (HTTP Request/Response) ValidatorvsFuelPHP
-
OpenAPI PSR-7 Message (HTTP Request/Response) ValidatorvsYii2
-
OpenAPI PSR-7 Message (HTTP Request/Response) ValidatorvsSymfony
README
NOTICE - THE PACKAGE HAS BEEN CONTRIBUTED TO THE PHP LEAGUE
Go to https://github.com/thephpleague/openapi-psr7-validator
This package is here for existing users only.
OpenAPI PSR-7 Message (HTTP Request/Response) Validator
This package can validate PSR-7 messages against OpenAPI (3.0.x) specifications expressed in YAML or JSON.
[](image.jpg)
Installation
composer require lezhnev74/openapi-psr7-validator
OpenAPI (OAS) Terms
There are some specific terms that are used in the package. These terms come from OpenAPI:
specification
- an OpenAPI document describing an API, expressed in JSON or YAML filedata
- actual thing that we validate against a specification, including body and metadataschema
- the part of the specification that describes the body of the request / responsekeyword
- properties that are used to describe the instance are called key words, or schema keywordspath
- a relative path to an individual endpointoperation
- a method that we apply on the path (likeget /password
)response
- described response (includes status code, content types etc)
How To Validate
ServerRequest Message
You can validate \Psr\Http\Message\ServerRequestInterface
instance like this:
$yamlFile = "api.yaml";
$jsonFile = "api.json";
$validator = (new \OpenAPIValidation\PSR7\ValidatorBuilder)->fromYamlFile($yamlFile)->getServerRequestValidator();
#or
$validator = (new \OpenAPIValidation\PSR7\ValidatorBuilder)->fromYaml(file_get_contents($yamlFile))->getServerRequestValidator();
#or
$validator = (new \OpenAPIValidation\PSR7\ValidatorBuilder)->fromJson(file_get_contents($jsonFile))->getServerRequestValidator();
#or
$validator = (new \OpenAPIValidation\PSR7\ValidatorBuilder)->fromJsonFile($jsonFile)->getServerRequestValidator();
#or
$schema = new \cebe\openapi\spec\OpenApi(); // generate schema object by hand
$validator = (new \OpenAPIValidation\PSR7\ValidatorBuilder)->fromSchema($schema)->getServerRequestValidator();
$match = $validator->validate($request);
As a result you would get and OperationAddress $match
which has matched the given request. If you already know
the operation which should match your request (i.e you have routing in your project), you can use
RouterRequestValidator
$address = new \OpenAPIValidation\PSR7\OperationAddress('/some/operation', 'post');
$validator = (new \OpenAPIValidation\PSR7\ValidatorBuilder)->fromSchema($schema)->getRoutedRequestValidator();
$validator->validate($address, $request);
This would simplify validation a lot and give you more performance.
Request Message
You can validate \Psr\Http\Message\RequestInterface
instance like this:
$yamlFile = "api.yaml";
$jsonFile = "api.json";
$validator = (new \OpenAPIValidation\PSR7\ValidatorBuilder)->fromYamlFile($yamlFile)->getRequestValidator();
#or
$validator = (new \OpenAPIValidation\PSR7\ValidatorBuilder)->fromYaml(file_get_contents($yamlFile))->getRequestValidator();
#or
$validator = (new \OpenAPIValidation\PSR7\ValidatorBuilder)->fromJson(file_get_contents($jsonFile))->getRequestValidator();
#or
$validator = (new \OpenAPIValidation\PSR7\ValidatorBuilder)->fromJsonFile($jsonFile)->getRequestValidator();
#or
$schema = new \cebe\openapi\spec\OpenApi(); // generate schema object by hand
$validator = (new \OpenAPIValidation\PSR7\ValidatorBuilder)->fromSchema($schema)->getRequestValidator();
$match = $validator->validate($request);
Response Message
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).
Example:
$yamlFile = "api.yaml";
$jsonFile = "api.json";
$validator = (new \OpenAPIValidation\PSR7\ValidatorBuilder)->fromYamlFile($yamlFile)->getResponseValidator();
#or
$validator = (new \OpenAPIValidation\PSR7\ValidatorBuilder)->fromYaml(file_get_contents($yamlFile))->getResponseValidator();
#or
$validator = (new \OpenAPIValidation\PSR7\ValidatorBuilder)->fromJson(file_get_contents($jsonFile))->getResponseValidator();
#or
$validator = (new \OpenAPIValidation\PSR7\ValidatorBuilder)->fromJsonFile($jsonFile)->getResponseValidator();
#or
$schema = new \cebe\openapi\spec\OpenApi(); // generate schema object by hand
$validator = (new \OpenAPIValidation\PSR7\ValidatorBuilder)->fromSchema($schema)->getResponseValidator();
$operation = new \OpenAPIValidation\PSR7\OperationAddress('/password/gen', 'get') ;
$validator->validate($operation, $request);
Reuse Schema After Validation
\OpenAPIValidation\PSR7\ValidatorBuilder
reads and compiles schema in memory as instance of \cebe\openapi\spec\OpenApi
. Validators use this instance to perform validation logic. You can reuse this instance after the validation like this:
$validator = (new \OpenAPIValidation\PSR7\ValidatorBuilder)->fromYamlFile($yamlFile)->getServerRequestValidator();
# or
$validator = (new \OpenAPIValidation\PSR7\ValidatorBuilder)->fromYamlFile($yamlFile)->getResponseValidator();
/** @var \cebe\openapi\spec\OpenApi */
$openApi = $validator->getSchema();
Request Message
\Psr\Http\Message\RequestInterface
validation is not implemented.
PSR-15 Middleware
PSR-15 middleware can be used like this:
$yamlFile = 'api.yaml';
$jsonFile = 'api.json';
$psr15Middleware = (new \OpenAPIValidation\PSR15\ValidationMiddlewareBuilder)->fromYamlFile($yamlFile)->getValidationMiddleware();
#or
$psr15Middleware = (new \OpenAPIValidation\PSR15\ValidationMiddlewareBuilder)->fromYaml(file_get_contents($yamlFile))->getValidationMiddleware();
#or
$psr15Middleware = (new \OpenAPIValidation\PSR15\ValidationMiddlewareBuilder)->fromJsonFile($jsonFile)->getValidationMiddleware();
#or
$psr15Middleware = (new \OpenAPIValidation\PSR15\ValidationMiddlewareBuilder)->fromJson(file_get_contents($jsonFile))->getValidationMiddleware();
#or
$schema = new \cebe\openapi\spec\OpenApi(); // generate schema object by hand
$validator = (new \OpenAPIValidation\PSR7\ValidationMiddlewareBuilder)->fromSchema($schema)->getValidationMiddleware();
SlimFramework Middleware
Slim framework uses slightly different middleware interface, so here is an adapter which you can use like this:
$yamlFile = 'api.yaml';
$jsonFile = 'api.json';
$psr15Middleware = (new \OpenAPIValidation\PSR15\ValidationMiddlewareBuilder)->fromYamlFile($yamlFile)->getValidationMiddleware();
#or
$psr15Middleware = (new \OpenAPIValidation\PSR15\ValidationMiddlewareBuilder)->fromYaml(file_get_contents($yamlFile))->getValidationMiddleware();
#or
$psr15Middleware = (new \OpenAPIValidation\PSR15\ValidationMiddlewareBuilder)->fromJsonFile($jsonFile)->getValidationMiddleware();
#or
$psr15Middleware = (new \OpenAPIValidation\PSR15\ValidationMiddlewareBuilder)->fromJson(file_get_contents($jsonFile))->getValidationMiddleware();
#or
$schema = new \cebe\openapi\spec\OpenApi(); // generate schema object by hand
$validator = (new \OpenAPIValidation\PSR7\ValidationMiddlewareBuilder)->fromSchema($schema)->getValidationMiddleware();
$slimMiddleware = new \OpenAPIValidation\PSR15\SlimAdapter($psr15Middleware);
/** @var \Slim\App $app */
$app->add($slimMiddleware);
Caching Layer / PSR-6 Support
PSR-7 Validator has a built-in caching layer (based on PSR-6 interfaces) which saves time on parsing OpenAPI specs. It is optional. You enable caching if you pass a configured Cache Pool Object to the static constructor like this:
// Configure a PSR-6 Cache Pool
$cachePool = new ArrayCachePool();
// Pass it as a 2nd argument
$validator = (new \OpenAPIValidation\PSR7\ValidatorBuilder)
->fromYamlFile($yamlFile)
->setCache($cachePool)
->getResponseValidator();
# or
\OpenAPIValidation\PSR15\ValidationMiddleware::fromYamlFile($yamlFile, $cachePool);
You can use ->setCache($pool, $ttl)
call for both PSR-7 and PSR-15 builder in order to set
proper expiration ttl in seconds (or explicit null
)
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.
Standalone OpenAPI Validator
The package contains a standalone validator which can validate any data against an OpenAPI schema like this:
$spec = <<<SPEC
schema:
type: string
enum:
- a
- b
SPEC;
$data = "c";
$spec = cebe\openapi\Reader::readFromYaml($spec);
# (optional) reference resolving
$spec->resolveReferences(new ReferenceContext($spec, "/"));
$schema = new cebe\openapi\spec\Schema($spec->schema);
try {
(new \OpenAPIValidation\Schema\SchemaValidator())->validate($data, $schema);
} catch(\OpenAPIValidation\Schema\Exception\KeywordMismatch $e) {
// you can evaluate failure details
// $e->keyword() == "enum"
// $e->data() == "c"
// $e->dataBreadCrumb()->buildChain() -- only for nested data
}
Custom Type Formats
As you know, OpenAPI allows you to add formats to types:
schema:
type: string
format: binary
This package contains a bunch of built-in format validators:
string
type:byte
date
date-time
email
hostname
ipv4
ipv6
uri
uuid
(uuid4)
number
typefloat
double
You can also add your own formats. Like this:
# A format validator must be a callable
# It must return bool value (true if format matched the data, false otherwise)
# A callable class:
$customFormat = new class()
{
function __invoke($value): bool
{
return $value === "good value";
}
};
# Or just a closure:
$customFormat = function ($value): bool {
return $value === "good value";
};
# Register your callable like this before validating your data
\OpenAPIValidation\Schema\TypeFormats\FormatsContainer::registerFormat('string', 'custom', $customFormat);
Exceptions
The package throws a list of various exceptions which you can catch and handle. There are some of them:
- Schema related:
\OpenAPIValidation\Schema\Exception\KeywordMismatch
- Indicates that data was not matched against a schema's keyword\OpenAPIValidation\Schema\Exception\TypeMismatch
- Validation fortype
keyword failed against a given data. For exampletype:string
and value is12
\OpenAPIValidation\Schema\Exception\FormatMismatch
- data mismatched a given type format. For exampletype: string, format: email
won't matchnot-email
.
- PSR7 Messages related:
\OpenAPIValidation\PSR7\Exception\NoContentType
- HTTP message(request/response) contains no Content-Type header. General HTTP errors.\OpenAPIValidation\PSR7\Exception\NoPath
- path is not found in the spec\OpenAPIValidation\PSR7\Exception\NoOperation
- operation os not found in the path\OpenAPIValidation\PSR7\Exception\NoResponseCode
- response code not found under the operation in the spec- Validation exceptions (check parent exception for possible root causes):
\OpenAPIValidation\PSR7\Exception\ValidationFailed
- generic exception for failed PSR-7 message\OpenAPIValidation\PSR7\Exception\Validation\InvalidBody
- body does not match schema\OpenAPIValidation\PSR7\Exception\Validation\InvalidCookies
- cookies does not match schema or missing required cookie\OpenAPIValidation\PSR7\Exception\Validation\InvalidHeaders
- header does not match schema or missing required header\OpenAPIValidation\PSR7\Exception\Validation\InvalidPath
- path does not match pattern or pattern values does not match schema\OpenAPIValidation\PSR7\Exception\Validation\InvalidQueryArgs
- query args does not match schema or missing required argument\OpenAPIValidation\PSR7\Exception\Validation\InvalidSecurity
- request does not match security schema or invalid security headers
- Request related:
\OpenAPIValidation\PSR7\Exception\MultipleOperationsMismatchForRequest
- request matched multiple operations in the spec, but validation failed for all of them.
Testing
You can run the tests with:
vendor/bin/phpunit
Contribution Guide
Feel free to open an Issue or add a Pull request. There is a certain code style that this package follows: doctrine/coding-standard.
To conform to this style please use a git hook, shipped with this package at .githooks/pre-commit
.
How to use it:
- Clone the package locally and navigate to the folder
- Create a symlink to the hook like this:
ln -s -f ../../.githooks/pre-commit .git/hooks/pre-commit
- Add execution rights:
chmod +x .git/hooks/pre-commit
- Now commit any new changes and the code will be checked and formatted accordingly.
- If there are any issues with your code, check the log here:
.phpcs-report.txt
Credits
People:
- Dmitry Lezhnev
- Carsten Brandt
- Samuel Nela
- Pavel Batanov
- Christopher L Bray
- David Pauli
- Jason Judge
- Yannick Chenot
- TarasBK
- Jason B. Standing
- Dmytro Demchyna
- Will Chambers
- Ignacio
- A big thank you to Henrik Karlström who kind of inspired me to work on this package.
Resources:
- Icons made by Freepik, licensed by CC 3.0 BY
- cebe/php-openapi package for Reading OpenAPI files
- slim3-psr15 package for Slim middleware adapter
License
The MIT License (MIT). Please see License.md
file for more information.
TODO
- [ ] Support Discriminator Object (note: apparently, this is not so straightforward, as discriminator can point to any external scheme)
*Note that all licence references and agreements mentioned in the OpenAPI PSR-7 Message (HTTP Request/Response) Validator README section above
are relevant to that project's source code only.