mixerapi / hal-view
为 CakePHP 提供的 Hypertext Application Language (HAL+JSON) 视图。
v2.0.3
2024-02-17 22:15 UTC
Requires
- php: ^8.1
- cakephp/cakephp: ^5.0
- mixerapi/core: ^2.0
Requires (Dev)
- josegonzalez/dotenv: ^3.2
- phpunit/phpunit: ^10.0
README
CakePHP 的 Hypertext Application Language (HAL+JSON) 视图。此插件支持链接、分页和嵌入式资源。一旦设置,任何带有 application/hal+json 的请求都将由该插件渲染。
目录
安装
!!! 注意 "" 如果已安装 MixerAPI,则可以跳过此步骤。
composer require mixerapi/hal-view bin/cake plugin load MixerApi/HalView
或者,在 composer 安装后,您可以手动在您的应用程序中加载该插件
# src/Application.php public function bootstrap(): void { // other logic... $this->addPlugin('MixerApi/HalView'); }
设置
您的控制器必须使用 RequestHandler 组件。这通常在您的 AppController 中加载。
# src/Controller/AppController.php public function initialize(): void { parent::initialize(); $this->loadComponent('RequestHandler'); // other logic... }
使用
对于 _link.self.href 支持,您需要在您想公开为 HAL 资源的对象上实现 MixerApi\HalView\HalResourceInterface。这会告知插件该实体应被视为 HAL 资源,并为映射器提供 _link.self.href URL
<?php declare(strict_types=1); namespace App\Model\Entity; use Cake\ORM\Entity; use MixerApi\HalView\HalResourceInterface; use Cake\Datasource\EntityInterface; class Actor extends Entity implements HalResourceInterface { // your various properties and logic /** * @param EntityInterface $entity * @return array|\string[][] */ public function getHalLinks(EntityInterface $entity): array { return [ 'self' => [ 'href' => '/actors/' . $entity->get('id') ] ]; } }
现在,对 /actors/149 端点的 HTTP GET 请求将使用 CakePHP 的原生序列化过程渲染 HAL
#src/Controller/ActorsController.php public function view($id = null) { $this->request->allowMethod('get'); $actor = $this->Actors->get($id, [ 'contain' => ['Films'], ]); $this->set('actor', $actor); $this->viewBuilder()->setOption('serialize', 'actor'); }
示例
{
"_links": {
"self": {
"href": "/actors/149"
}
},
"id": 149,
"first_name": "RUSSELL",
"last_name": "TEMPLE",
"modified": "2006-02-15T04:34:33+00:00",
"_embedded": {
"films": [
{
"id": 53,
"title": "BANG KWAI",
"description": "A Epic Drama of a Madman And a Cat who must Face a A Shark in An Abandoned Amusement Park",
"release_year": "2006",
"language_id": 1,
"rental_duration": 5,
"rental_rate": "2.99",
"length": 87,
"replacement_cost": "25.99",
"rating": "NC-17",
"special_features": "Commentaries,Deleted Scenes,Behind the Scenes",
"modified": "2006-02-15T05:03:42+00:00"
"_links": {
"self": {
"href": "/films/53"
}
}
}
]
}
}
如果您的实体没有实现该接口,则在序列化时它仍然会作为 HAL 资源返回,但会缺少 _links 属性。集合请求也可以不使用该接口正常工作,例如
#src/Controller/ActorsController.php public function index() { $this->request->allowMethod('get'); $actors = $this->paginate($this->Actors, [ 'contain' => ['Films'], ]); $this->set(compact('actors')); $this->viewBuilder()->setOption('serialize', 'actors'); }
示例
{
"_links": {
"self": {
"href": "/actors?page=3"
},
"next": {
"href": "/actors?page=4"
},
"prev": {
"href": "/actors?page=2"
},
"first": {
"href": "/actors?page=1"
},
"last": {
"href": "/actors?page=11"
}
},
"count": 20,
"total": 207,
"_embedded": {
"actors": [
{
"id": 1,
"first_name": "PENELOPE",
"last_name": "GUINESS",
"modified": "2006-02-15T04:34:33+00:00"
"_embedded": {
"films": [
{
"id": 1,
"title": "ACADEMY DINOSAUR",
"description": "A Epic Drama of a Feminist And a Mad Scientist who must Battle a Teacher in The Canadian Rockies",
"release_year": "2006",
"language_id": 1,
"rental_duration": 6,
"rental_rate": "0.99",
"length": 86,
"replacement_cost": "20.99",
"rating": "PG",
"special_features": "Deleted Scenes,Behind the Scenes",
"modified": "2006-02-15T05:03:42+00:00"
}
]
}
}
]
}
}
如果 Actor 和 Film 实体实现了 MixerApi\HalView\HalResourceInterface,则上述示例将为每个序列化实体包含 _links 属性。
自己试一试
# json curl -X GET "https://:8765/actors" -H "accept: application/hal+json"
序列化
可选地,您可以使用 JsonSerializer 手动将数据序列化为 HAL。这是 HalJsonView 主类使用的相同类。示例
use MixerApi\HalView\JsonSerializer; # json $json = (new JsonSerializer($data))->asJson(JSON_PRETTY_PRINT); // asJson argument is optional # array $hal = (new JsonSerializer($data))->getData(); # json with `_links.self.href` and pagination meta data use Cake\Http\ServerRequest; use Cake\View\Helper\PaginatorHelper; $json = (new JsonSerializer($data, new ServerRequest(), new PaginatorHelper()))->asJson();