PHPackages                             liquidrazor/dto-api-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. liquidrazor/dto-api-bundle

ActiveSymfony-bundle[API Development](/categories/api)

liquidrazor/dto-api-bundle
==========================

A DTO-first Symfony bundle for building boring JSON APIs with streaming responses and autogenerated OpenAPI documentation.

v0.1.6(3mo ago)02.7k11MITPHPPHP &gt;=8.3CI passing

Since Sep 18Pushed 2mo agoCompare

[ Source](https://github.com/LiquidRazor/DTOApi)[ Packagist](https://packagist.org/packages/liquidrazor/dto-api-bundle)[ RSS](/packages/liquidrazor-dto-api-bundle/feed)WikiDiscussions main Synced today

READMEChangelog (3)Dependencies (42)Versions (14)Used By (1)

LiquidRazor/DtoApiBundle
========================

[](#liquidrazordtoapibundle)

> **DTO-first API toolkit for Symfony 7.x / 8.x**
> Attributes for request/response contracts, automatic validation, safe (de)serialization, streaming (NDJSON/SSE), OpenAPI generation, and Symfony Profiler integration.

---

[![Latest Stable Version](https://camo.githubusercontent.com/e782948ec02b605f85f00e73fb7e79e5853c0a575983360d43dfbb6542350097/68747470733a2f2f706f7365722e707567782e6f72672f6c697175696472617a6f722f64746f2d6170692d62756e646c652f762f737461626c65)](https://packagist.org/packages/liquidrazor/dto-api-bundle)[![Total Downloads](https://camo.githubusercontent.com/ca147b381f5356489e7ce904b0634960ad3c29e4a96c8230ec2c5ebb3b8d3d54/68747470733a2f2f706f7365722e707567782e6f72672f6c697175696472617a6f722f64746f2d6170692d62756e646c652f646f776e6c6f616473)](https://packagist.org/packages/liquidrazor/dto-api-bundle)[![License](https://camo.githubusercontent.com/f5161310fec86493767ed059f6114c5da53f66fe0551b537e2817af71a532946/68747470733a2f2f706f7365722e707567782e6f72672f6c697175696472617a6f722f64746f2d6170692d62756e646c652f6c6963656e7365)](LICENCE)

---

✨ Features
----------

[](#-features)

- **Attributes** for requests, responses, operations, and properties
- **Validation bridge**: property metadata → Symfony constraints (no YAML/XML)
- **Safe request hydration** via events (no fatals, no leaks)
- **Response mapping** with global defaults (422/500)
- **Error handling**: exceptions → mapped error DTOs
- **Streaming helpers**: NDJSON (`application/x-ndjson`) and SSE (`text/event-stream`)
- **OpenAPI 3.1/3.0.3** generator with Swagger UI + Redoc
- **Profiler panel**: metadata, DTOs, violations, and the actual response used

---

🧰 Requirements
--------------

[](#-requirements)

- PHP **8.3+**
- Symfony **7.0** or **8.0**
- packages: (already present in composer.json)
    - `ext-json`
    - `symfony/dependency-injection`
    - `symfony/config`
    - `symfony/http-kernel`
    - `symfony/serializer`
    - `symfony/property-access`
    - `symfony/options-resolver`
    - `symfony/validator`
    - `monolog/monolog`

---

📦 Install
---------

[](#-install)

```
composer require liquidrazor/dto-api-bundle
```

Enable the bundle (if Flex doesn’t auto-register):

config/bundles.php

```
return [
    ...
    LiquidRazor\DtoApiBundle\LiquidRazorDtoApiBundle::class => ['all' => true],
];
```

⚙️ Configuration
----------------

[](#️-configuration)

### Responses

[](#responses)

```
# config/packages/liquidrazor_dto_api.yaml
liquidrazor_dto_api:
  normalizer_priority: 10
  strict_types: true
  openapi_version: '3.1.0'   # or '3.0.3' for Redoc OSS compatibility
  default_responses:
    422:
        class: LiquidRazor\DtoApiBundle\Response\ValidationErrorResponse
        description: 'Validation error'
    500:
        class: LiquidRazor\DtoApiBundle\Response\ErrorResponse
        description: 'Server error'
```

Edit the file and set up any custom response classes (and|or descriptions)

This is the default configuration and should be there if flex auto-registered the bundle. Otherwise it's probably missing and should be added.

### Routes

[](#routes)

add the following to your routes.yaml (if not already added by symfony flex)

```
# config/routes/liquidrazor_dto_api.yaml
liquidrazor_dto_api:
  resource: '@LiquidRazorDtoApiBundle/Resources/config/routes.php'
```

You now get:

- `/_schema/openapi.json` — OpenAPI spec
- `/_docs/swagger` — Swagger UI
- `/_docs/redoc` — Redoc UI

🚀 Usage Guides
--------------

[](#-usage-guides)

### 1. Request DTO

[](#1-request-dto)

```
use LiquidRazor\DtoApiBundle\Lib\Attributes\{DtoApiRequest, DtoApiProperty};

#[DtoApiRequest(name: 'UserInput')]
final readonly class UserInputDto
{
    public function __construct(
        #[DtoApiProperty(type: 'string', required: true, minLength: 3)]
        public ?string $name = null,

        #[DtoApiProperty(type: 'integer', required: true, minimum: 18, maximum: 100)]
        public ?int $age = null,
    ) {}
}
```

Validation is automatic — missing/invalid fields trigger a 422 ValidationErrorResponse (unless you override the default response).

### 2. Response DTO

[](#2-response-dto)

```
use LiquidRazor\DtoApiBundle\Lib\Attributes\{DtoApiResponse, DtoApiProperty};

#[DtoApiResponse(status: 200, description: 'User created')]
final readonly class UserResponse
{
    public function __construct(
        #[DtoApiProperty(type: 'string')] public string $id,
        #[DtoApiProperty(type: 'string')] public string $name,
    ) {}
}
```

### 3. Controller

[](#3-controller)

```
use LiquidRazor\DtoApiBundle\Lib\Attributes\{DtoApi, DtoApiOperation};
use Symfony\Component\Routing\Attribute\Route;

#[DtoApi]
final class UserController
{
    #[DtoApiOperation(
        summary: 'Create user',
        description: 'Accepts a UserInputDto and returns a UserResponse',
        request: UserInputDto::class,
        response: [UserResponse::class] // 422/500 added by defaults
    )]
    #[Route('/users', methods: ['POST'])]
    public function create(UserInputDto $request): UserResponse
    {
        return new UserResponse(id: uniqid(), name: $request->name);
    }
}
```

### 4. Error Handling

[](#4-error-handling)

All exceptions are logged

Mapped to a declared `#[DtoApiResponse(status: …)]` if present

Fallback: ErrorResponse (500 JSON)

### 5. Streaming

[](#5-streaming)

#### 5.1 NDJSON

[](#51--ndjson)

```
#[DtoApiOperation(summary: 'NDJSON counter')]
#[DtoApiResponse(status: 200, stream: true, contentType: 'application/x-ndjson')]
#[Route('/stream/ndjson', methods: ['GET'])]
public function streamNdjson(): iterable
{
    for ($i=1; $i $i, 'ts' => (new \DateTimeImmutable())->format(DATE_ATOM)];
        usleep(200_000);
    }
}
```

#### 5.2 SSE

[](#52--sse)

```
use LiquidRazor\DtoApiBundle\Lib\Streaming\SseEvent;

#[DtoApiOperation(summary: 'SSE clock')]
#[DtoApiResponse(status: 200, stream: true, contentType: 'text/event-stream')]
#[Route('/stream/sse', methods: ['GET'])]
public function sseClock(): iterable
{
    for ($i=0; $i date(DATE_ATOM)], 'tick', (string)$i, 3000);
        sleep(1);
    }
}
```

### 6. Profiler

[](#6-profiler)

Symfony Profiler panel shows:

Operation metadata (summary, request/response DTOs)

Request violations (422 errors)

Which response mapping was actually used.

🧩 Extensibility
---------------

[](#-extensibility)

- Custom constraints: tag dtoapi.constraint\_contributor to translate custom hints into Symfony constraints
- Global defaults: override liquidrazor\_dto\_api.default\_responses
- OpenAPI hooks: extend components, security, servers, parameters

📍 Known limitations
-------------------

[](#-known-limitations)

- Very strict CSP may require self-hosting Swagger/Redoc assets instead of using CDNs

📝 License
---------

[](#-license)

MIT

🙌 Credits
---------

[](#-credits)

Built by LiquidRazor with help from Symfony’s excellent components.

###  Health Score

44

—

FairBetter than 90% of packages

Maintenance83

Actively maintained with recent releases

Popularity23

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 83.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~32 days

Recently: every ~47 days

Total

7

Last Release

93d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/4306922?v=4)[Noramarth](/maintainers/Noramarth)[@Noramarth](https://github.com/Noramarth)

---

Top Contributors

[![Noramarth](https://avatars.githubusercontent.com/u/4306922?v=4)](https://github.com/Noramarth "Noramarth (30 commits)")[![hktr92](https://avatars.githubusercontent.com/u/7689151?v=4)](https://github.com/hktr92 "hktr92 (4 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (1 commits)")[![devin-ai-integration[bot]](https://avatars.githubusercontent.com/in/811515?v=4)](https://github.com/devin-ai-integration[bot] "devin-ai-integration[bot] (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/liquidrazor-dto-api-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/liquidrazor-dto-api-bundle/health.svg)](https://phpackages.com/packages/liquidrazor-dto-api-bundle)
```

###  Alternatives

[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

585.6M577](/packages/shopware-core)[easycorp/easyadmin-bundle

Admin generator for Symfony applications

4.3k17.9M388](/packages/easycorp-easyadmin-bundle)[open-dxp/opendxp

Content &amp; Product Management Framework (CMS/PIM)

9421.6k61](/packages/open-dxp-opendxp)[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.5k5.9M739](/packages/sylius-sylius)[pimcore/pimcore

Content &amp; Product Management Framework (CMS/PIM/E-Commerce)

3.8k3.8M508](/packages/pimcore-pimcore)[shopware/platform

The Shopware e-commerce core

3.4k1.5M3](/packages/shopware-platform)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
