Skip to content

Commit 2432aaa

Browse files
fix: add missing resource link functionality (#644)
Closes #643
1 parent d28b444 commit 2432aaa

File tree

4 files changed

+68
-26
lines changed

4 files changed

+68
-26
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file. This projec
88
### Fixed
99

1010
- [#642](https://github.com/cloudcreativity/laravel-json-api/pull/642) Add missing resource meta functionality.
11+
- [#643](https://github.com/cloudcreativity/laravel-json-api/issues/643) Add missing resource link functionality.
1112

1213
## [6.0.0] - 2023-02-14
1314

docs/basics/schemas.md

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -384,20 +384,35 @@ By default all resource objects will be encoded with their `self` link, e.g.:
384384
}
385385
```
386386

387-
You can change this behaviour by overloading the `getResourceLinks` or `getIncludedResourceLinks` methods.
388-
For example:
387+
You can change this behaviour by implementing the `getResourceLinks` method. For example, if you do not want any links
388+
to be serialized:
389389

390390
```php
391391
class Schema extends SchemaProvider
392392
{
393393
// ...
394394

395-
public function getResourceLinks($resource)
395+
public function getResourceLinks($resource): ?array
396396
{
397-
$links = parent::getResourceLinks($resource);
398-
$links['foo'] = $this->createLink('posts/foo');
397+
return null;
398+
}
399+
}
400+
```
401+
402+
If you return an array without any `self` key in it, the `self` link will be automatically added. If you do not want
403+
the `self` link to be set, set the array key `self` to `false`.
404+
405+
```php
406+
class Schema extends SchemaProvider
407+
{
408+
// ...
399409

400-
return $links;
410+
public function getResourceLinks($resource): array
411+
{
412+
return [
413+
// "self" will automatically be added as it is not set to false.
414+
'foo' => $this->createLink('posts/foo'),
415+
];
401416
}
402417

403418
}
@@ -423,9 +438,6 @@ This would result in the following resource object:
423438
> The `createLink` method allows you to pass in link meta and set whether the URI is relative to the API or an
424439
absolute path.
425440

426-
If you want to only change the links when the resource is appearing in the `included` section of the JSON API
427-
document, overload the `getIncludedResourceLinks()` method instead.
428-
429441
## Meta
430442

431443
You can add top-level `meta` to your resource object using the `getResourceMeta()` method

src/Schema/Schema.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,30 @@ public function getRelationships($resource, ContextInterface $context): iterable
102102
}
103103
}
104104

105+
/**
106+
* @inheritDoc
107+
*/
108+
public function getLinks($resource): iterable
109+
{
110+
$links = [];
111+
112+
if (method_exists($this->provider, 'getResourceLinks')) {
113+
$links = $this->provider->getResourceLinks($resource);
114+
}
115+
116+
if ($links === null) {
117+
return [];
118+
}
119+
120+
$self = $links[LinkInterface::SELF] ?? null;
121+
122+
if (!$self instanceof LinkInterface && $self !== false) {
123+
$links[LinkInterface::SELF] = $this->getSelfLink($resource);
124+
}
125+
126+
return $links;
127+
}
128+
105129
/**
106130
* @inheritDoc
107131
*/

src/Schema/SchemaProvider.php

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
abstract class SchemaProvider implements SchemaProviderInterface
3131
{
3232
/**
33-
* @var string|null
33+
* @var string
3434
*/
3535
protected string $resourceType = '';
3636

@@ -134,10 +134,8 @@ public function getSelfSubUrl(object $resource = null): string
134134
*/
135135
public function getSelfSubLink(object $resource): LinkInterface
136136
{
137-
return $this->factory->createLink(
138-
true,
137+
return $this->createLink(
139138
$this->getSelfSubUrl($resource),
140-
false,
141139
);
142140
}
143141

@@ -146,12 +144,8 @@ public function getSelfSubLink(object $resource): LinkInterface
146144
*/
147145
public function getRelationshipSelfLink(object $resource, string $field): LinkInterface
148146
{
149-
$url = $this->getRelationshipSelfUrl($resource, $field);
150-
151-
return $this->factory->createLink(
152-
true,
153-
$url,
154-
false,
147+
return $this->createLink(
148+
$this->getRelationshipSelfUrl($resource, $field),
155149
);
156150
}
157151

@@ -160,12 +154,8 @@ public function getRelationshipSelfLink(object $resource, string $field): LinkIn
160154
*/
161155
public function getRelationshipRelatedLink(object $resource, string $field): LinkInterface
162156
{
163-
$url = $this->getRelationshipRelatedUrl($resource, $field);
164-
165-
return $this->factory->createLink(
166-
true,
167-
$url,
168-
false,
157+
return $this->createLink(
158+
$this->getRelationshipRelatedUrl($resource, $field),
169159
);
170160
}
171161

@@ -210,6 +200,21 @@ protected function getContext(): ContextInterface
210200
return $this->context;
211201
}
212202

213-
throw new RuntimeException('No currenct context set.');
203+
throw new RuntimeException('No current context set.');
204+
}
205+
206+
/**
207+
* Create a link.
208+
*
209+
* This method was on the v1 schema provider, so is provided here for backwards compatibility.
210+
*
211+
* @param string $subHref
212+
* @param null|mixed $meta
213+
* @param bool $treatAsHref
214+
* @return LinkInterface
215+
*/
216+
protected function createLink(string $subHref, array $meta = null, bool $treatAsHref = false): LinkInterface
217+
{
218+
return $this->factory->createLink(!$treatAsHref, $subHref, !empty($meta), $meta);
214219
}
215220
}

0 commit comments

Comments
 (0)