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 1mo ago

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 22% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity5

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity46

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

1560d 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

[stripe/stripe-php

Stripe PHP Library

4.0k143.3M480](/packages/stripe-stripe-php)[twilio/sdk

A PHP wrapper for Twilio's API

1.6k92.9M272](/packages/twilio-sdk)[knplabs/github-api

GitHub API v3 client

2.2k15.8M187](/packages/knplabs-github-api)[facebook/php-business-sdk

PHP SDK for Facebook Business

90121.9M34](/packages/facebook-php-business-sdk)[meilisearch/meilisearch-php

PHP wrapper for the Meilisearch API

73813.7M114](/packages/meilisearch-meilisearch-php)[google/gax

Google API Core for PHP

263103.1M454](/packages/google-gax)

PHPackages © 2026

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