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


README

CI PHPStan Level 8 Spec Conformance PHP Version Symfony Version Packagist OpenSSF Scorecard

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

  1. Register the bundle in config/bundles.php:
return [
    AlexFigures\Symfony\Bridge\Symfony\Bundle\JsonApiBundle::class => ['all' => true],
];
  1. Create configuration in config/packages/jsonapi.yaml:
jsonapi:
    route_prefix: '/api'
    pagination:
        default_size: 25
        max_size: 100
  1. 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 = [];
}
  1. Implement data layer (see Doctrine Integration Guide)

  2. 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, ilike operators
  • Logical Operators - Combine filters with and, or, not for 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

For Advanced Users

For Contributors

๐Ÿ“– Complete Documentation Index โ†’

๐Ÿ†• Recent Updates

New Features

  • ๐Ÿ†• Path Aliases - Expose clean API paths that map to complex Doctrine relationships using propertyPath parameter
    #[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, filtering
  • GET /api/{type}/{id} - Single resource with sparse fieldsets
  • GET /api/{type}/{id}/relationships/{rel} - Relationship linkage
  • GET /api/{type}/{id}/{rel} - Related resources
  • Query parsing: include, fields[TYPE], sort, page[number], page[size]
  • Pagination with self, first, prev, next, last links
  • Compound documents with included array
  • Sparse fieldsets for performance optimization

Write Operations

  • POST /api/{type} โ†’ 201 Created with Location header
  • PATCH /api/{type}/{id} โ†’ 200 OK with updated resource
  • DELETE /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.