api-skeletons/laravel-hal-doctrine

基于 Doctrine 元数据的 HAL

0.8.2 2022-02-03 01:00 UTC

This package is auto-updated.

Last update: 2024-08-29 05:44:29 UTC


README

Build Status Code Coverage PHP Version Laravel Version Total Downloads License

此库为 Doctrine 提供了 laravel-hal 的 hydrator。无需手动为实体创建每个 hydrator,此库将内省实体并生成包括指向其他实体和一对多关系以及嵌入多对一和一对一实体的链接在内的 HAL。

分组最小配置文件允许排除字段和关联,并为每个实体配置路由。

用法

创建 hydrator 管理器

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,
        ];
    }
}

提取实体

use App\Hal\HydratorManager;

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

将生成类似于以下 HAL 响应

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

配置

需要一个 hal-doctrine.php 配置文件。将包含的配置发布到您的项目中

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

此库使用 Laminas Hydrator 直接从实体中提取数据。您必须将此配置添加到您的 doctrine.php 配置文件中

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

命名策略

默认命名策略使用 Inflector 的 urlize() 方法将 'associationName' 更改为 'association-name'。如果您不希望以这种方式命名关系或路由,则创建自己的命名策略并将其分配到配置文件中。

路由命名

当使用 routeNamePatterns 创建路由名称时,实体名称变为 $namingStrategy->route($entityName),例如根据示例配置的 api.short-name::fetch

过滤集合

对于提取的相关集合,将创建与 ApiSkeletons\Doctrine\QueryBuilder\Filter\Applicator 兼容的过滤选项的链接,以将集合数据过滤为仅提取的实体。例如

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

将过滤到专辑链接,其中 album.artist = 1。为了在您的应用程序中处理这些 URL,在控制器操作中实现 ApiSkeletons\Doctrine\QueryBuilder\Filter\Applicator

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();
}

有关更多详细示例,请参阅 doctrine-querybuilder-filter 文档

多个对象管理器

要为除 default 配置部分以外的配置配置 hydrator,扩展 Doctrine Hydrator

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

然后在您的 hal-doctrine.php 配置文件中,创建一个名为 secondary 的新部分,并将 entityManager 设置为您的第二个实体管理器。