gpht / openapi-symfony-validator
OpenAPI validation library for Symfony applications with PHPUnit integration
Requires
- php: ^8.4
- league/openapi-psr7-validator: ^0.22
- nyholm/psr7: ^1.8
- symfony/browser-kit: ^6.0|^7.0
- symfony/framework-bundle: ^6.0|^7.0
- symfony/psr-http-message-bridge: ^6.0|^7.0
- symfony/yaml: ^6.0|^7.0
Requires (Dev)
- carthage-software/mago: 1.0.0-beta.15
- phpunit/phpunit: ^10.0|^11.0
- vimeo/psalm: ^7.0.0-beta11
README
A PHP library for validating Symfony application requests and responses against OpenAPI specifications. This library provides PHPUnit integration through traits and automatic test case generation.
Features
- π Easy PHPUnit Integration: Use the
OpenApiValidationTrait
in your test classes - π Automatic Test Generation: Generate test cases from OpenAPI specifications
- π― Request/Response Validation: Validate both HTTP requests and responses
- πΊοΈ Path Mapping: Map OpenAPI paths to your actual application routes
- π§ͺ Symfony Integration: Works seamlessly with Symfony's test client
Installation
Install via Composer:
composer require --dev gpht/openapi-symfony-validator
Requirements
- PHP ^8.4
- Symfony ^6.0|^7.0
- PHPUnit ^10.0|^11.0
Usage
Basic Usage with Trait
The easiest way to use this library is with the OpenApiValidationTrait
:
<?php declare(strict_types=1); namespace App\Tests\Imperative; use Gpht\OpenapiSymfonyValidator\OpenApiValidationTrait; use Symfony\Bundle\FrameworkBundle\KernelBrowser; use Symfony\Component\Security\Core\User\OidcUser; final class OpenApiValidationTest extends ImperativeTestCase { use OpenApiValidationTrait; public function client(): KernelBrowser { $user = new OidcUser( userIdentifier: 'test-user-123', roles: ['ROLE_USER'], sub: 'test-user-123', email: 'test@example.com', ); return self::$client->loginUser($user); } public static function openApiPath(): string { return __DIR__ . '/../../api/sync/public/openapi.yaml'; } public static function apiMap(): array { return [ '/workflow-service/product' => '/public/product', '/workflow-service/favorite-photos/update-favorite-photo/{guestAccessId}/{photoId}/{role}' => '/public/favorite-photos/update-favorite-photo/{guestAccessId}/{photoId}/{role}', '/workflow-service/favorite-photos/get-favorite-for-access-code/{guestAccessId}' => '/public/favorite-photos/get-favorite-for-access-code/{guestAccessId}', ]; } }
The trait will automatically:
- Generate test cases from your OpenAPI specification
- Create PHPUnit data providers
- Execute tests for each endpoint with the configured client
- Validate both requests and responses against the OpenAPI schema
OpenAPI Parameter Requirements
Important: All parameters in your OpenAPI specification must have either an example
or default
value. The library uses these values to generate test requests.
paths: /products: get: summary: Get products parameters: - name: category in: query description: Filter products by category schema: type: string example: "prints" - name: page in: query description: Page number for pagination schema: type: integer default: 1 example: 1 - name: limit in: query description: Number of items per page schema: type: integer default: 10 example: 25 - name: userId in: path description: User identifier required: true schema: type: string example: "user-123"
Path Mapping
The apiMap()
method maps OpenAPI paths to your actual application routes:
- Key: The path as defined in your OpenAPI specification
- Value: The actual route path in your Symfony application
public static function apiMap(): array { return [ // OpenAPI path => Actual application path '/api/users/{id}' => '/public/users/{id}', '/api/products' => '/internal/products', ]; }
Direct Usage (Advanced)
For complex validation scenarios, you can use the OpenApiValidator
class directly or fall back to the underlying league/openapi-psr7-validator
library:
use Gpht\OpenapiSymfonyValidator\OpenApiValidator; use League\OpenAPIValidation\PSR7\ValidatorBuilder; // Using OpenApiValidator directly $validator = new OpenApiValidator('/path/to/openapi.yaml', $pathMappings); $validator->validateRequestResponse($client, 'GET', '/actual/path', '/openapi/path', [], [], null); // Using league/openapi-psr7-validator directly for complex cases $validatorBuilder = new ValidatorBuilder(); $requestValidator = $validatorBuilder->fromYamlFile('/path/to/openapi.yaml')->getRequestValidator(); $responseValidator = $validatorBuilder->getResponseValidator(); // Custom validation logic...
Development
Code Quality Tools
This project uses Mago for code formatting and linting, plus Psalm for static analysis:
# Format code composer format # Check formatting composer format-check # Run linter composer lint # Run static analysis composer psalm # Run all checks composer format-check && composer lint && composer psalm
Testing
Run the test suite:
composer test
GitHub Actions
The project includes a comprehensive CI pipeline that runs:
- Mago formatting checks
- Mago linting
- Psalm static analysis
- PHPUnit tests
License
MIT
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Run the code quality checks:
composer format-check && composer lint && composer psalm
- Run tests:
composer test
- Submit a pull request
Requirements for OpenAPI Specifications
- All parameters must have
example
ordefault
values - Path parameters are automatically replaced in both OpenAPI and actual paths
- Query parameters without values will be excluded from minimal test cases
- The library supports all standard HTTP methods (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS)