Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

20 Commits

Repository files navigation

MixerApi HAL View

Latest Version on PackagistBuildCoverage StatusMixerApiCakePHPMinimum PHP Version

A Hypertext Application Language (HAL+JSON) View for CakePHP. This plugin supports links, pagination, and embedded resources. Once setup any request with application/hal+json will be rendered by this plugin.

Table of Contents

Installation

!!! note "" You can skip this step if MixerAPI is installed.

composer require mixerapi/hal-viewbin/cake plugin load MixerApi/HalView

Alternatively after composer installing you can manually load the plugin in your Application:

# src/Application.phppublicfunctionbootstrap(): void
{
// other logic...$this->addPlugin('MixerApi/HalView');
}

Setup

Your controllers must be using the RequestHandler component. This is typically loaded in your AppController.

# src/Controller/AppController.phppublicfunctioninitialize(): void
{
parent::initialize();
$this->loadComponent('RequestHandler');
// other logic...
}

Usage

For _link.self.href support you will need to implement MixerApi\HalView\HalResourceInterface on entities that you want to expose as HAL resources. This informs the plugin that the Entity should be treated as a HAL resource and provides the mapper with a _link.self.href URL:

<?phpdeclare(strict_types=1);
namespaceApp\Model\Entity;
useCake\ORM\Entity;
useMixerApi\HalView\HalResourceInterface;
useCake\Datasource\EntityInterface;
class Actor extends Entity implements HalResourceInterface
{
// your various properties and logic/** * @param EntityInterface $entity * @return array|\string[][] */publicfunctiongetHalLinks(EntityInterface$entity): array
{
return [
'self' => [
'href' => '/actors/' . $entity->get('id')
]
];
}
}

Now an HTTP GET to the /actors/149 endpoint will render HAL using the CakePHP native serialization process:

#src/Controller/ActorsController.phppublicfunctionview($id = null)
{
$this->request->allowMethod('get');
$actor = $this->Actors->get($id, [
'contain' => ['Films'],
]);
$this->set('actor', $actor);
$this->viewBuilder()->setOption('serialize', 'actor');
}
Example

{
"_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"
}
}
}
]
}
}

If your Entity does not implement the interface it will still be returned as HAL resource when serialized, but minus the _links property. Collection requests will work without this interface as well, example:

#src/Controller/ActorsController.phppublicfunctionindex()
{
$this->request->allowMethod('get');
$actors = $this->paginate($this->Actors, [
'contain' => ['Films'],
]);
$this->set(compact('actors'));
$this->viewBuilder()->setOption('serialize', 'actors');
}
Example

{
"_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"
}
]
}
}
]
}
}

If the Actor and Film entities were implementing MixerApi\HalView\HalResourceInterface then the example above would include the _links property for each serialized entity.

Try it out for yourself:

# jsoncurl -X GET "http://localhost:8765/actors" -H "accept: application/hal+json"

Serializing

Optionally, you can manually serialize data into HAL using JsonSerializer. This is the same class that the main HalJsonView uses. Example:

useMixerApi\HalView\JsonSerializer;
# json$json = (newJsonSerializer($data))->asJson(JSON_PRETTY_PRINT); // asJson argument is optional# array$hal = (newJsonSerializer($data))->getData();
# json with `_links.self.href` and pagination meta datauseCake\Http\ServerRequest;
useCake\View\Helper\PaginatorHelper;
$json = (newJsonSerializer($data, newServerRequest(), newPaginatorHelper()))->asJson();

About

A Hypertext Application Language (HAL+JSON) View for CakePHP [READ-ONLY]

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages