api-skeletons / laravel-hal-doctrine
基于 Doctrine 元数据的 HAL
Requires
- php: ^8.0
- api-skeletons/doctrine-querybuilder-filter: ^1.2
- api-skeletons/laravel-hal: ^5.0.2
- doctrine/doctrine-laminas-hydrator: ^2.2
- laravel-doctrine/orm: ^1.7
Requires (Dev)
- doctrine/annotations: ^1.13.2
- doctrine/coding-standard: ^9.0
- doctrine/dbal: ^2.13.7||^3.1.1
- orchestra/testbench: ^6.23
- phpunit/phpunit: ^9.5
README
此库为 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
设置为您的第二个实体管理器。