PHPackages                             digital-craftsman/deserializing-connection - 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. [Database &amp; ORM](/categories/database)
4. /
5. digital-craftsman/deserializing-connection

ActiveSymfony-bundle[Database &amp; ORM](/categories/database)

digital-craftsman/deserializing-connection
==========================================

Get DTOs directly from the database

0.7.2(2mo ago)02.4k—3.6%MITPHPPHP 8.4.\*|8.5.\*CI passing

Since Nov 10Pushed 2mo agoCompare

[ Source](https://github.com/digital-craftsman-de/deserializing-connection)[ Packagist](https://packagist.org/packages/digital-craftsman/deserializing-connection)[ RSS](/packages/digital-craftsman-deserializing-connection/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (22)Versions (19)Used By (0)

Get DTOs directly from the database
===================================

[](#get-dtos-directly-from-the-database)

A Symfony bundle to get DTOs directly from the database. It's a simple and efficient way to get data from the database and convert it into DTOs without to much noise in your code.

As it's a central part of an application, it's tested thoroughly (including mutation testing).

[![Latest Stable Version](https://camo.githubusercontent.com/efdaf184137beb141290a42f116a0559828165cce27f58eb9b16b52471e04366/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f737461626c652d302e372e322d626c7565)](https://packagist.org/packages/digital-craftsman/deserializing-connection)[![PHP Version Require](https://camo.githubusercontent.com/2f2005e31dc46e3c057be679d712cd9c4486aafcd26810f33ab48992af8d4971/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d382e34253743382e352d356235643935)](https://packagist.org/packages/digital-craftsman/deserializing-connection)[![codecov](https://camo.githubusercontent.com/80eaad44a8ec391043218f1132fc0c12a858a9d8b2300e16c739c51152914b44/68747470733a2f2f636f6465636f762e696f2f67682f6469676974616c2d6372616674736d616e2d64652f646573657269616c697a696e672d636f6e6e656374696f6e2f6272616e63682f6d61696e2f67726170682f62616467652e7376673f746f6b656e3d424c304a4b5a594c4247)](https://codecov.io/gh/digital-craftsman-de/deserializing-connection)[![Packagist Downloads](https://camo.githubusercontent.com/3ee3ced3c10a3b92ae31934efd8b453c79dc084bf78b40f2bc256047367a9c54/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6469676974616c2d6372616674736d616e2f646573657269616c697a696e672d636f6e6e656374696f6e)](https://camo.githubusercontent.com/3ee3ced3c10a3b92ae31934efd8b453c79dc084bf78b40f2bc256047367a9c54/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6469676974616c2d6372616674736d616e2f646573657269616c697a696e672d636f6e6e656374696f6e)[![Packagist License](https://camo.githubusercontent.com/dbe84d08c940e807ba7e2ac7a1b2ef0248b39b46f6c53d47e794be2cb0e8fb4b/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6469676974616c2d6372616674736d616e2f646573657269616c697a696e672d636f6e6e656374696f6e)](https://camo.githubusercontent.com/dbe84d08c940e807ba7e2ac7a1b2ef0248b39b46f6c53d47e794be2cb0e8fb4b/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6469676974616c2d6372616674736d616e2f646573657269616c697a696e672d636f6e6e656374696f6e)

Installation and configuration
------------------------------

[](#installation-and-configuration)

Install package through composer:

```
composer require digital-craftsman/deserializing-connection
```

> ⚠️ This bundle can be used (and is being used) in production, but hasn't reached version 1.0 yet. Therefore, there will be breaking changes between minor versions. I'd recommend that you require the bundle only with the current minor version like `composer require digital-craftsman/deserializing-connection:0.7.*`. Breaking changes are described in the releases and [the changelog](./CHANGELOG.md). Updates are described in the [upgrade guide](./UPGRADE.md).

Usage
-----

[](#usage)

### Deserializing connection

[](#deserializing-connection)

When you want DTOs, read models or value objects, you can use the `DeserializingConnection` to get them directly from the database.

Given the following DTO:

```
final readonly class User
{
    public function __construct(
        public UserId $userId,
        public string $name,
        public ProjectIdList $accessibleProjects,
    ) {
    }
}
```

A call for one might look like this:

```
$user = $this->deserializingConnection->getOne(
    sql:  $userId,
    ],
    decoderTypes: [
        'accessibleProjects' => DecoderType::JSON,
    ],
);
```

These are the offered methods:

- `getOne` to return one object or an exception when no result is found.
- `findOne` like `getOne`, but returns `null` when no result is found.
- `getOneFromSingleValue` to return one object from a single value or an exception when no result is found.
- `findOneFromSingleValue` like `getOneFromSingleValue`, but returns `null` when no result is found.
- `findArray` to return an array of objects.
- `findGenerator` to return a generator that yields the objects.

You can use `getOneFromSingleValue` when the denormalization step needs a single value instead of an associative array. This could look like this:

```
$duration = $this->deserializingConnection->getOneFromSingleValue(
    sql:  $projectId,
    ],
);
```

### Decoding types

[](#decoding-types)

Part of the magic is the conversion from database types to PHP types. For example, when your SQL returns a JSON string, you usually need to convert it into an associative array prior to serialization. Here you just need to supply `decoderTypes` with the column name and the type of decoder you want to use. There are utilities that can handle nullable values or create a empty array when a JSON returns null (relevant for `jsonb_agg` calls). These are the available decoder types which are all pretty self-explanatory:

- `BOOL`
- `NULLABLE_BOOL`
- `INT`
- `NULLABLE_INT`
- `FLOAT`
- `NULLABLE_FLOAT`
- `JSON`
- `NULLABLE_JSON`
- `JSON_WITH_EMPTY_ARRAY_ON_NULL`

### Decoding connection

[](#decoding-connection)

When you want to get a scalar value or do more complex stuff, you can use the underlying `DecodingConnection`. It offers the following methods:

- `fetchOne`
- `fetchAssociative`
- `fetchAllAssociative`
- `fetchFirstColumn`
- `fetchInt`
- `fetchBool`

`fetchInt` and `fetchBool` will throw custom exceptions when there are no values or they are not of the expected type.

### Result transformers

[](#result-transformers)

There are cases where you're not able to do everything in the SQL query. For example when you want to calculate a value based on data of the environment or information that is only available on runtime. In those cases, you can use result transformers to run callbacks before the data is deserialized into the DTO.

This can look like this for the following DTO:

```
final readonly class User
{
    public function __construct(
        public UserId $userId,
        public string $name,
        public string $companyLink,
    ) {
    }
}
```

```
$this->deserializingConnection->getOne(
    sql:  $userId,
    ],
    decoderTypes: [
        'company' => DecoderType::JSON,
    ],
    resultTransformers: [
        ResultTransformer::toTransformAndRename(
            key: 'companyLink',
            denormalizeResultToClass: CompanyLink::class,
            transformer: fn(CompanyLink $companyLink) => $this->router->generate(
                'company_show',
                [
                    'companyId' => $companyLink->companyId,
                ],
            ),
            isTransformedResultNormalized: false,
            renameTo: 'link',
        ),
    ],
);
```

The available variants of `ResultTransformer` are:

- `toTransform`
- `toRename`
- `toTransformAndRename`

The "rename" variants are simply renaming the property into the supplied name.

Additional documentation for the key (how it can be used in a multi level result and for arrays) can be found in the [`ResultTransformerKey class`](./src/Serializer/DTO/ResultTransformerKey.php).

### Normalizers

[](#normalizers)

For easier normalization, use the [`digital-craftsman/self-aware-normalizers`](https://github.com/digital-craftsman-de/self-aware-normalizers) package which is required by this package.

### Doctrine types

[](#doctrine-types)

For easier doctrine types, use the [`digital-craftsman/self-aware-normalizers`](https://github.com/digital-craftsman-de/self-aware-normalizers) package which is required by this package.

Additional documentation
------------------------

[](#additional-documentation)

- [Changelog](./CHANGELOG.md)
- [Upgrade guide](./UPGRADE.md)

###  Health Score

45

—

FairBetter than 93% of packages

Maintenance87

Actively maintained with recent releases

Popularity21

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity55

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% 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 ~57 days

Total

16

Last Release

64d ago

PHP version history (2 changes)v0.1.0-alpha.1PHP 8.3.\*|8.4.\*

0.7.0PHP 8.4.\*|8.5.\*

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/30455298?v=4)[digital-craftsman](/maintainers/digital-craftsman)[@digital-craftsman](https://github.com/digital-craftsman)

---

Top Contributors

[![christian-kolb](https://avatars.githubusercontent.com/u/1033270?v=4)](https://github.com/christian-kolb "christian-kolb (16 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/digital-craftsman-deserializing-connection/health.svg)

```
[![Health](https://phpackages.com/badges/digital-craftsman-deserializing-connection/health.svg)](https://phpackages.com/packages/digital-craftsman-deserializing-connection)
```

###  Alternatives

[laravel-doctrine/orm

An integration library for Laravel and Doctrine ORM

8425.3M87](/packages/laravel-doctrine-orm)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.3M152](/packages/sulu-sulu)[kimai/kimai

Kimai - Time Tracking

4.6k7.4k1](/packages/kimai-kimai)[bolt/core

🧿 Bolt Core

585142.5k54](/packages/bolt-core)[ec-cube/ec-cube

EC-CUBE EC open platform.

78527.0k1](/packages/ec-cube-ec-cube)[open-dxp/opendxp

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

7310.3k29](/packages/open-dxp-opendxp)

PHPackages © 2026

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