PHPackages                             api-skeletons/laravel-hal-doctrine - 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. api-skeletons/laravel-hal-doctrine

ActiveLibrary[API Development](/categories/api)

api-skeletons/laravel-hal-doctrine
==================================

Doctrine Metadata based HAL

0.8.2(4y ago)081MITPHPPHP ^8.0

Since Feb 1Pushed 4y ago1 watchersCompare

[ Source](https://github.com/API-Skeletons/laravel-hal-doctrine)[ Packagist](https://packagist.org/packages/api-skeletons/laravel-hal-doctrine)[ RSS](/packages/api-skeletons-laravel-hal-doctrine/feed)WikiDiscussions main Synced today

READMEChangelog (3)Dependencies (9)Versions (4)Used By (0)

Laravel HAL Doctrine
====================

[](#laravel-hal-doctrine)

[![Build Status](https://github.com/API-Skeletons/laravel-hal-doctrine/actions/workflows/continuous-integration.yml/badge.svg)](https://github.com/API-Skeletons/laravel-hal-doctrine/actions/workflows/continuous-integration.yml?query=branch%3Amain)[![Code Coverage](https://camo.githubusercontent.com/e10c0e1e02602f95f1c8d478bce838799c8937f667b5a4c34189d415881b396e/68747470733a2f2f636f6465636f762e696f2f67682f4150492d536b656c65746f6e732f6c61726176656c2d68616c2d646f637472696e652f6272616e63682f6d61696e2f6772617068732f62616467652e737667)](https://codecov.io/gh/API-Skeletons/laravel-hal-doctrine/branch/main)[![PHP Version](https://camo.githubusercontent.com/d43f3018edfd35e43d9669f893ce52781d51f11ac9240420a3dce982b6ae8af1/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e302532622d626c7565)](https://img.shields.io/badge/PHP-7.3%20to%208.0%2b-blue)[![Laravel Version](https://camo.githubusercontent.com/7330d8a5139fa5b0654b55716554c94de722670528ade3db570ad7e3e09c3156/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d382e782532622d726564)](https://img.shields.io/badge/Laravel-5.7%20to%208.x-red)[![Total Downloads](https://camo.githubusercontent.com/f0d4d06cd160b178873e2ec57c4756a6d7c9c071e29d3914a752781a3fba3685/68747470733a2f2f706f7365722e707567782e6f72672f6170692d736b656c65746f6e732f6c61726176656c2d68616c2d646f637472696e652f646f776e6c6f616473)](//packagist.org/packages/api-skeletons/laravel-hal-doctrine)[![License](https://camo.githubusercontent.com/c801e6a67d8b2a0ef615b51bf3517935e2a2814435e0a72e3b69f716d5ba99eb/68747470733a2f2f706f7365722e707567782e6f72672f6170692d736b656c65746f6e732f6c61726176656c2d68616c2d646f637472696e652f6c6963656e7365)](//packagist.org/packages/api-skeletons/laravel-hal-doctrine)

This library provides a hydrator for [laravel-hal](https://github.com/API-Skeletons/laravel-hal)for Doctrine. Instead of manually creating every hydrator for your entities, this library will introspect an entity and generate the HAL for it including links to other entities and collections for one to many relationships and embedding many to one and one to one entities.

A grouped minimal configuration file allows for excluded fields and associations and configures the routes for each entity.

Use
---

[](#use)

### Create a hydrator manager

[](#create-a-hydrator-manager)

```
namespace App\HAL;

use ApiSkeletons\Laravel\HAL\HydratorManager as HALHydratorManager;

final class HydratorManager extends HALHydratorManager
{
    public function __construct()
    {
        $this->classHydrators = [
            // This wildcard entry is used as an example and may not be exactly what you need
            '*' => \ApiSkeletons\Laravel\HAL\Doctrine\DoctrineHydrator::class,
        ];
    }
}
```

### Extract an entity

[](#extract-an-entity)

```
use App\Hal\HydratorManager;

public function fetch(Entity\Artist $artist): array
{
    return (new HydratorManager())->extract($artist)->toArray();
}
```

will result in a HAL response like

```
{
  "_links": {
    "self": {
      "href": "https://website/artist/1"
    },
    "albums": {
      "href": "https://website/album?filter[artist]=1"
    }
  },
  "id": 1,
  "name": "Grateful Dead"
}
```

Configuration
-------------

[](#configuration)

A `hal-doctrine.php` configuration file is required. Publish the included config to your project:

```
php artisan vendor:publish --tag=config
```

```
$config = [
    'default' => [
        'entityManager' => EntityManager::class,
        'routeNamePatterns' => [
            'entity' => 'api.{entityName}::fetch',
            'collection' => 'api.{entityName}::fetchAll',
        ],
        // All entities configuration is optional
        'entities' => [
            \App\ORM\Entity\Artist::class => [
                // Override route patterns
                'routesNames' => [
                    'entity' => 'artist::fetch',
                    'collection' => 'artist::fetchAll',
                ],
                // List of fields and associations to exclude
                'exclude' => [
                    'alias',
                ],
            ],
        ],
    ],
];
```

### Doctrine\\Laminas\\Hydrator\\DoctrineObject

[](#doctrinelaminashydratordoctrineobject)

The Laminas Hydrator is used by this library to extract data directly from entities. You must add this configuration to your `doctrine.php` configuration file:

```
'custom_hydration_modes' = [
    'hal-doctrine' => \Doctrine\Laminas\Hydrator\DoctrineObject::class,
],
```

### Naming Strategy

[](#naming-strategy)

The default naming strategy uses the Inflector's `urlize()` method to change 'associationName' into 'association-name'. If this is not the way you want to name your relationsihps or routes then create your own naming strategy and assign it in the config file.

Route naming
------------

[](#route-naming)

When using the `routeNamePatterns` to create a route name, the entity name becomes `$namingStrategy->route($entityName)`such as `api.short-name::fetch` according to the example configuration.

Filtering Collections
---------------------

[](#filtering-collections)

For extracted related collections, links will be created with filter options compatible with `ApiSkeletons\Doctrine\QueryBuilder\Filter\Applicator` to filter the collection data to just the extracted entity. For example

```
  "_links": {
    ...
    "album": {
      "href": "https://website/album?filter[artist]=1"
    }
```

The link to the Album will be filtered where `album.artist = 1`. In order to process these URLs in your application, implement `ApiSkeletons\Doctrine\QueryBuilder\Filter\Applicator` in your controller action:

```
use ApiSkeletons\Doctrine\QueryBuilder\Filter\Applicator;

public function fetchAll(EntityManager $entityManager): array
{
    $applicator = new Applicator($entityManager, Entity\Album::class);
    $queryBuilder = $applicator($_REQUEST['filter']);

    return (new HydratorManager())
        ->paginate('albums', collect($queryBuilder->getQuery()->getResult()))->toArray();
}
```

See the [documentation for doctrine-querybuilder-filter](https://github.com/API-Skeletons/doctrine-querybuilder-filter#doctrine-querybuilder-filter)for more detailed examples.

Multiple Object Managers
------------------------

[](#multiple-object-managers)

To configure a hydrator for other than the `default` configuration section, extend the Doctrine Hydrator

```
class SecondDoctrineHydrator extends ApiSkeletons\Laravel\HAL\Doctrine\DoctrineHydrator
{
    protected string $configurationSection = 'secondary';
}
```

Then in your `hal-doctrine.php` configuration file, create a new section titled `secondary` and set the `entityManager` to your second Entity Manager.

###  Health Score

22

—

LowBetter than 21% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity5

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity47

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 ~0 days

Total

3

Last Release

1612d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/49dd7d9dba889ac674b0da447d9c1e69d1128dc3ccbaef98ba83d6ee519fc2d6?d=identicon)[tom\_anderson](/maintainers/tom_anderson)

---

Top Contributors

[![TomHAnderson](https://avatars.githubusercontent.com/u/493920?v=4)](https://github.com/TomHAnderson "TomHAnderson (38 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/api-skeletons-laravel-hal-doctrine/health.svg)

```
[![Health](https://phpackages.com/badges/api-skeletons-laravel-hal-doctrine/health.svg)](https://phpackages.com/packages/api-skeletons-laravel-hal-doctrine)
```

###  Alternatives

[exsyst/swagger

A php library to manipulate Swagger specifications

35916.4M7](/packages/exsyst-swagger)[hubspot/api-client

Hubspot API client

24016.2M20](/packages/hubspot-api-client)[badaso/core

The API &amp; platform builder, build your apps 10x faster even more, it's open source &amp; 100% free !

1.3k16.3k10](/packages/badaso-core)[pocketmine/bedrock-protocol

An implementation of the Minecraft: Bedrock Edition protocol in PHP

172445.0k15](/packages/pocketmine-bedrock-protocol)[botman/driver-telegram

Telegram driver for BotMan

93459.5k6](/packages/botman-driver-telegram)[api-skeletons/doctrine-orm-graphql

GraphQL Type Driver for Doctrine ORM

126.2k1](/packages/api-skeletons-doctrine-orm-graphql)

PHPackages © 2026

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