Links
Introduction
A resource object may have a links object containing links related to the resource. By default we include the self
link for each resource that is recommended by the JSON:API specification. However you are also able to provide other non-standard links if required.
In JSON:API links can either be strings, or a JSON object containing a href
member (the string URI) and a meta
member. The meta
object would contain non-standard meta-information about the link.
Self Link
By default each resource object will contain a self
link. This is the URL at which the resource can be read, updated and deleted. Its inclusion is recommended by the JSON:API specification.
The URL for this link is generated by appending the resource type
and id
to the Server's URI namespace. As the URL is generated using Laravel's url
helper, the hostname will also be included.
For example, if our server has a namespace of /api/v1
, the posts
resource with an id
of 123
will have have a links
member:
{
"type": "posts",
"id": "123",
"attributes": {
"content": "...",
"createdAt": "2020-07-10T12:42:17.000000Z",
"title": "Hello World!",
"updatedAt": "2020-07-10T13:53:01.000000Z"
},
"links": {
"self": "http://localhost/api/v1/posts/123"
}
}
TIP
The self
link returned by the resource object is also used when generating relationship links.
Customising the URL
If you need different logic for the self
link, implement the selfUrl
method on your resource:
/**
* Get the resource's `self` link URL.
*
* @return string
*/
public function selfUrl(): string
{
if ($this->selfUri) {
return $this->selfUri;
}
return $this->selfUri = url('/foo/bar/posts', $this->id());
}
Note that we cache the calculated value so that it only has to be calculated once.
Adding Meta
If you would like to add meta
to the self
link, implement the selfMeta
method:
/**
* Get meta for the `self` link.
*
* @return array
*/
protected function selfMeta(): array
{
return [
'foo' => 'bar',
'baz' => 'bat',
];
}
For example, this would result in the following posts
resource object:
{
"type": "posts",
"id": "123",
"attributes": {
"content": "...",
"createdAt": "2020-07-10T12:42:17.000000Z",
"title": "Hello World!",
"updatedAt": "2020-07-10T13:53:01.000000Z"
},
"links": {
"self": {
"href": "http://localhost/api/v1/posts/123",
"meta": {
"foo": "bar",
"baz": "bat"
}
}
}
}
Non-Standard Links
The JSON:API specification is unclear as to whether other non-standard links are allowed on a resource object. The implication is only defined links members are allowed, and that more members may be specified in the future.
This means we would generally discourage adding non-standard links to your resource objects. However, if you do need to add non-standard links, implement the links
method on your resource:
use LaravelJsonApi\Core\Document\Link;
use LaravelJsonApi\Core\Document\Links;
/**
* Get the resource's links.
*
* @param \Illuminate\Http\Request|null $request
* @return Links
*/
public function links($request): Links
{
return new Links(
$this->selfLink(),
new Link(
'download',
url('/api/v1/posts', [$this->id(), 'download']),
['foo' => 'bar']
),
);
}
As you can see, we return a Links
object. Each argument provided to the constructor is a Link
object. Note that we call $this->selfLink()
to ensure the self
link is included.
When creating a Link
object, you must provide two arguments: the member name of the link, and the URL. An optional third member allows meta to be added.
Our example above would generate the following posts
resource:
{
"type": "posts",
"id": "123",
"attributes": {
"content": "...",
"createdAt": "2020-07-10T12:42:17.000000Z",
"title": "Hello World!",
"updatedAt": "2020-07-10T13:53:01.000000Z"
},
"links": {
"self": "http://localhost/api/v1/posts/123",
"download": {
"href": "http://localhost/api/v1/posts/123/download",
"meta": {
"foo": "bar"
}
}
}
}