alexfigures / symfony-jsonapi-bundle
JSON:API 1.1 bundle for Symfony 7 with DX-first design
Fund package maintenance!
AlexFigures
Installs: 9
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 0
Forks: 0
Open Issues: 13
Type:symfony-bundle
pkg:composer/alexfigures/symfony-jsonapi-bundle
Requires
- php: ^8.2
- symfony/config: ^7.1
- symfony/dependency-injection: ^7.1
- symfony/event-dispatcher: ^7.1
- symfony/http-foundation: ^7.1
- symfony/http-kernel: ^7.1
- symfony/property-access: ^7.1
- symfony/property-info: ^7.1
- symfony/routing: ^7.1
- symfony/serializer: ^7.1
- symfony/uid: ^7.1
- symfony/validator: ^7.1
Requires (Dev)
- deptrac/deptrac: ^4.2
- doctrine/dbal: ^3.8
- doctrine/orm: ^3.0
- friendsofphp/php-cs-fixer: ^3.64
- infection/infection: ^0.29
- jbelien/phpstan-sarif-formatter: ^1.2
- phpstan/phpstan: ^1.11
- phpunit/phpunit: ^11.0
- rector/rector: ^1.0
- roave/backward-compatibility-check: ^8.14
- spatie/phpunit-snapshot-assertions: ^5.2
- symfony/cache: ^7.3
- symfony/phpunit-bridge: ^7.1
- dev-main / 0.1.x-dev
- v0.1.25
- v0.1.24
- v0.1.23
- v0.1.22
- v0.1.21
- v0.1.20
- v0.1.19
- v0.1.18
- v0.1.17
- v0.1.16
- v0.1.15
- v0.1.14
- v0.1.13
- v0.1.12
- v0.1.11
- v0.1.10
- v0.1.9
- v0.1.8
- v0.1.7
- v0.1.6
- v0.1.5
- v0.1.4-alpha.1
- v0.1.4-alpha
- v0.1.3-alpha
- v0.1.2-alpha.1
- v0.1.2-alpha
- v0.1.1-alpha
- v0.1.0-alpha
- dev-dependabot/composer/doctrine/dbal-tw-4.4
- dev-dependabot/composer/symfony/phpunit-bridge-tw-8.0
- dev-dependabot/composer/symfony/routing-tw-8.0
- dev-dependabot/composer/symfony/validator-tw-8.0
- dev-dependabot/composer/symfony/property-info-tw-8.0
- dev-dependabot/composer/symfony/serializer-tw-8.0
- dev-dependabot/composer/symfony/uid-tw-8.0
- dev-dependabot/github_actions/actions/checkout-6
- dev-dependabot/github_actions/actions/upload-artifact-5
- dev-openapi-spec
- dev-custom-filters
- dev-read-fix
- dev-dependabot/composer/phpunit/phpunit-tw-12.4
- dev-dependabot/composer/doctrine/dbal-tw-4.3
- dev-dependabot/github_actions/github/codeql-action-4
- dev-dependabot/composer/infection/infection-tw-0.31
- dev-dependabot/github_actions/ossf/scorecard-action-2.4.3
This package is auto-updated.
Last update: 2025-12-03 10:11:37 UTC
README
Production-ready JSON:API 1.1 implementation for Symfony with complete filtering, automatic eager loading, and zero N+1 queries.
๐ Quick Start
Installation
composer require alexfigures/symfony-jsonapi-bundle
Requirements:
- PHP 8.3 or higher
- Symfony 7.1 or higher
- Doctrine ORM 3.0+ (optional, for database integration)
Basic Setup
- Register the bundle in
config/bundles.php:
return [ AlexFigures\Symfony\Bridge\Symfony\Bundle\JsonApiBundle::class => ['all' => true], ];
- Create configuration in
config/packages/jsonapi.yaml:
jsonapi: route_prefix: '/api' pagination: default_size: 25 max_size: 100
- Define your first resource:
use AlexFigures\Symfony\Resource\Attribute\JsonApiResource; use AlexFigures\Symfony\Resource\Attribute\Id; use AlexFigures\Symfony\Resource\Attribute\Attribute; use AlexFigures\Symfony\Resource\Attribute\Relationship; #[JsonApiResource(type: 'articles')] final class Article { #[Id] #[Attribute] public string $id; #[Attribute] public string $title; #[Relationship(toMany: true, targetType: 'comments')] public array $comments = []; }
-
Implement data layer (see Doctrine Integration Guide)
-
Start using your API:
# Get all articles curl http://localhost:8000/api/articles # Filter, sort, and include relationships (no N+1 queries!) curl "http://localhost:8000/api/articles?filter[status][eq]=published&sort=-createdAt&include=author,tags" # Advanced filtering with multiple conditions curl "http://localhost:8000/api/articles?filter[and][0][status][eq]=published&filter[and][1][viewCount][gte]=100" # Create new article curl -X POST \ -H "Content-Type: application/vnd.api+json" \ -d '{"data": {"type": "articles", "attributes": {"title": "Hello"}}}' \ http://localhost:8000/api/articles # Interactive API documentation open http://localhost:8000/_jsonapi/docs
๐ Complete Getting Started Guide โ ๐ Interactive API Docs โ
โ Compatibility Matrix
| JsonApiBundle | PHP | Symfony | Doctrine ORM |
|---|---|---|---|
main branch |
8.2 ยท 8.3 ยท 8.4 | 7.1 ยท 7.2 ยท 7.3 | 3.0+ |
| Latest release | 8.2+ | 7.1+ | 3.0+ |
CI runs the full test suite across PHP 8.2โ8.4 with both stable and lowest-dependency sets to guarantee forwards and backwards compatibility inside each supported Symfony minor.
Tested Databases:
- PostgreSQL 16+
- MySQL 8.0+
- MariaDB 11+
- SQLite 3.x
๐ฏ Key Features
๐ Advanced Filtering & Querying
- Complex Filters - Support for
eq,ne,gt,gte,lt,lte,in,nin,like,ilikeoperators - Logical Operators - Combine filters with
and,or,notfor complex queries - Relationship Filtering - Filter by nested relationship fields:
filter[author.name]=John - Whitelist-based Security - Only explicitly allowed fields can be filtered using
#[FilterableFields]
# Complex filtering example curl "api/articles?filter[and][0][status][eq]=published&filter[and][1][or][0][viewCount][gte]=100&filter[and][1][or][1][featured][eq]=true"
๐ Smart Relationship Handling
- Zero N+1 Queries - Automatic eager loading with optimized JOINs
- Deep Includes - Include nested relationships:
include=author.company,tags - Relationship Linking Policies - Control how relationships are validated (
VERIFY,ALLOW_ORPHANS) - Path Aliases - Expose clean API paths that map to complex Doctrine relationships
#[Relationship(
toMany: true,
targetType: 'tags',
propertyPath: 'articleTags.tag', // Clean API: specialTags โ complex path
linkingPolicy: RelationshipLinkingPolicy::VERIFY
)]
private Collection $specialTags;
๐ Flexible Sorting & Pagination
- Multi-field Sorting - Sort by multiple fields:
sort=title,-createdAt,author.name - Relationship Sorting - Sort by nested relationship fields
- Cursor & Offset Pagination - Both pagination strategies supported
- Configurable Limits - Set default and maximum page sizes
๐ก๏ธ Production-Ready Security
- Strict Denormalization - Reject unknown fields by default (
ALLOW_EXTRA_ATTRIBUTES=false) - Field Whitelisting - Explicit control over filterable/sortable fields
- Validation Integration - Full Symfony Validator integration
- Error Collection - Collect and return all validation errors at once
๐ Developer Experience
- Attribute-Based Configuration - No YAML/XML, everything in PHP attributes
- Auto-Generated OpenAPI - Interactive Swagger UI documentation
- Custom Route Support - Define custom endpoints with automatic JSON:API formatting
- Response Factory - Fluent API for building JSON:API responses in custom controllers
#[JsonApiResource(type: 'articles')] #[FilterableFields(['title', new FilterableField('author', inherit: true)])] #[SortableFields(['title', 'createdAt', new SortableField('author', inherit: true)])] final class Article { #[Id] #[Attribute] public string $id; #[Attribute] public string $title; #[Relationship(targetType: 'authors')] public Author $author; }
โก Performance Optimizations
- Automatic Query Optimization - Smart JOINs and SELECT field limiting
- Batch Operations - Efficient bulk create/update/delete
- Caching Support - HTTP caching headers and response caching
- Database Agnostic - Works with PostgreSQL, MySQL, MariaDB, SQLite
๐ง Extensibility
- Custom Handlers - Build complex business logic with automatic transaction management
- Event System - Hook into request/response lifecycle
- Custom Serialization - Override default serialization behavior
- Middleware Support - Standard Symfony middleware integration
๐ Documentation
For New Users
- Getting Started Guide - Build your first API in 5 minutes
- Swagger UI & OpenAPI - Interactive API documentation
- Configuration Reference - Complete configuration options
- Doctrine Integration - Production-ready data layer
- Examples & Recipes - Real-world code examples
- Custom Routes - Define custom endpoints with attributes
- Response Factory - Build JSON:API responses in custom controllers
For Advanced Users
- Path Aliases - Expose clean API paths that map to complex Doctrine relationships
- Advanced Features - Profiles, hooks, events, caching
- Custom Handlers - Handler-based custom routes with automatic transaction management
- Public API Reference - Stable API documentation
- Troubleshooting Guide - Common issues and solutions
For Contributors
- Contributing Guide - How to contribute
- Testing Guide - Running tests (unit, functional, integration with Docker)
- Architecture Review - Design and extensibility
- BC Policy - Backward compatibility guarantees
๐ Complete Documentation Index โ
๐ Recent Updates
New Features
- ๐ Path Aliases - Expose clean API paths that map to complex Doctrine relationships using
propertyPathparameter#[Relationship( toMany: true, targetType: 'tags', propertyPath: 'articleTags.tag' // API: specialTags โ Doctrine: articleTags.tag )] private Collection $specialTags; - Custom Route Handlers - Build custom endpoints with automatic transaction management and JSON:API response formatting (docs)
- Response Factory - Fluent API for building JSON:API responses in custom controllers (docs)
- Criteria Builder - Add custom filters and conditions to JSON:API queries in custom route handlers (docs)
- Custom Route Attributes - Define custom endpoints using
#[JsonApiCustomRoute]attribute (docs) - Media Type Configuration - Configure different media types for different endpoints (e.g., docs, sandbox)
- Docker-based Integration Tests - Run integration tests against real databases using Docker (docs)
Testing Improvements
- Docker Test Environment - Integration tests now run in Docker with PostgreSQL, MySQL, and MariaDB
- Conformance Tests - Snapshot-based tests ensure JSON:API specification compliance
- Mutation Testing - Infection configured with 70% MSI threshold
- Quality Gates - PHPStan level 8, Deptrac architecture rules, BC checks
Run tests with:
make test # Unit and functional tests make docker-test # Integration tests in Docker make qa-full # Full QA suite (tests, static analysis, mutation testing)
See TESTING.md for complete testing documentation.
โจ Features
Production-Ready Features โญ
โ Complete Filtering System - All operators (eq, ne, lt, lte, gt, gte, like, in, isnull, between) with SQL injection protection โ Automatic Eager Loading - Zero N+1 queries with automatic JOINs for includes โ Generic Doctrine Repository - Works out of the box, no custom code needed โ Relationship Pagination - Proper pagination for all relationship endpoints โ PostgreSQL Optimized - Tested and optimized for PostgreSQL โ Custom Route Handlers - Build custom endpoints with automatic transaction management and JSON:API formatting
Core Features
โ
JSON:API 1.1 Compliance - 97.8% specification coverage (132/135 requirements)
โ
Attribute-Driven - No XML/YAML configuration needed
โ
Auto-Generated Endpoints - No controller boilerplate
โ
Configurable Route Naming - Choose between snake_case and kebab-case
โ
Custom Route Attributes - Define custom endpoints with PHP attributes
โ
Query Parameters - include, fields, sort, page, filter
โ
Relationships - To-one and to-many with full CRUD
โ
Write Operations - POST, PATCH, DELETE with validation
โ
Atomic Operations - Batch operations in single transaction
โ
Interactive Docs - Swagger UI / Redoc integration
โ
Response Factory - Build JSON:API responses in custom controllers
Read Operations
GET /api/{type}- Collection with pagination, sorting, filteringGET /api/{type}/{id}- Single resource with sparse fieldsetsGET /api/{type}/{id}/relationships/{rel}- Relationship linkageGET /api/{type}/{id}/{rel}- Related resources- Query parsing:
include,fields[TYPE],sort,page[number],page[size] - Pagination with
self,first,prev,next,lastlinks - Compound documents with
includedarray - Sparse fieldsets for performance optimization
Write Operations
POST /api/{type}โ201 Createdwith Location headerPATCH /api/{type}/{id}โ200 OKwith updated resourceDELETE /api/{type}/{id}โ204 No Content- Transactional execution via
TransactionManager - Client-generated ID support (configurable per type)
- Strict input validation with detailed error responses
- Relationship modification endpoints (optional)
Advanced Features
- Profiles (RFC 6906) - Extend JSON:API with custom semantics
- Hooks System - Intercept and modify request processing
- Event System - React to resource changes
- HTTP Caching - ETag, Last-Modified, surrogate keys
- Custom Operators - Extend filtering capabilities
- Cache Invalidation - CDN/reverse proxy support
- Media Type Configuration - Configure different media types for different endpoints
- Criteria Builder - Add custom filters and conditions to JSON:API queries in custom handlers
๐ See all features โ
๐ Backward Compatibility
JsonApiBundle follows Semantic Versioning:
- MAJOR versions may contain breaking changes
- MINOR versions add features in a backward-compatible manner
- PATCH versions contain bug fixes only
Public API (Stable)
The following are guaranteed to maintain backward compatibility:
- โ
Contract Interfaces (
src/Contract/) - Data layer contracts - โ
Resource Attributes (
src/Resource/Attribute/) -#[JsonApiResource],#[Attribute], etc. - โ
Configuration Schema - All
jsonapi:configuration options
๐ Public API Reference โ ๐ BC Policy โ ๐ Upgrade Guide โ
Pre-1.0 Notice
โ ๏ธ Versions 0.x may introduce breaking changes in MINOR versions. Pin to exact MINOR version:
{
"require": {
"jsonapi/symfony-jsonapi-bundle": "~0.1.0"
}
}
๐ Interactive API Documentation
The bundle provides automatic OpenAPI 3.1 documentation with interactive UI:
Access Documentation
Swagger UI (Interactive):
http://localhost:8000/_jsonapi/docs
OpenAPI Specification (JSON):
http://localhost:8000/_jsonapi/openapi.json
Features
- ๐จ Two themes: Swagger UI (default) or Redoc
- ๐ Try it out: Test endpoints directly from browser
- ๐ Auto-generated: Reflects all resources and relationships
- ๐ Environment-aware: Disable in production
Configuration
# config/packages/jsonapi.yaml jsonapi: docs: generator: openapi: enabled: true title: 'My API' version: '1.0.0' ui: enabled: true route: '/_jsonapi/docs' theme: 'swagger' # or 'redoc'
Production: Disable in config/packages/prod/jsonapi.yaml:
jsonapi: docs: ui: enabled: false
๐ Swagger UI Documentation โ
๐ Example Response
{
"jsonapi": { "version": "1.1" },
"links": {
"self": "http://localhost/api/articles?page[number]=1&page[size]=10",
"first": "http://localhost/api/articles?page[number]=1&page[size]=10",
"last": "http://localhost/api/articles?page[number]=3&page[size]=10",
"next": "http://localhost/api/articles?page[number]=2&page[size]=10"
},
"data": [
{
"type": "articles",
"id": "1",
"attributes": {
"title": "Getting Started with JSON:API",
"createdAt": "2025-10-07T10:00:00+00:00"
},
"relationships": {
"author": {
"links": {
"self": "http://localhost/api/articles/1/relationships/author",
"related": "http://localhost/api/articles/1/author"
},
"data": { "type": "authors", "id": "1" }
}
},
"links": {
"self": "http://localhost/api/articles/1"
}
}
],
"included": [
{
"type": "authors",
"id": "1",
"attributes": { "name": "Alice" },
"links": { "self": "http://localhost/api/authors/1" }
}
],
"meta": {
"total": 25,
"page": 1,
"size": 10
}
}
๐ ๏ธ Development & Testing
Quick Commands
# Install dependencies composer install # or make install # Run tests make test # Unit and functional tests (no Docker required) make docker-test # Integration tests with real databases make test-all # All test suites # Code quality make stan # PHPStan static analysis (level 8) make cs-fix # Fix code style (PSR-12) make rector # Automated refactoring make mutation # Mutation testing (70% MSI threshold) make deptrac # Architecture rules validation make bc-check # Backward compatibility check # Full QA pipeline make qa-full # Run all quality checks
See TESTING.md for detailed testing documentation.
๐ค Community & Governance
- ๐ฎ Need help? Read our Support guide for documentation links, discussion forums, and escalation paths.
- ๐ Contributions welcome! See the CONTRIBUTING.md for coding standards and workflow.
- โค๏ธ Be excellent to each other. Participation is governed by the Code of Conduct.
- ๐ก Report vulnerabilities privately. Follow the steps in SECURITY.md.
- ๐งญ Stay up to date. Watch Discussions and subscribe to release drafts for roadmap updates.