8000 [Docs] Move 0.5 upgrade guide into its own file · m-bymike/laravel-json-api@31eef39 · GitHub
[go: up one dir, main page]

Skip to content

Commit 31eef39

Browse files
committed
[Docs] Move 0.5 upgrade guide into its own file
1 parent 02ea9cd commit 31eef39

File tree

2 files changed

+363
-360
lines changed

2 files changed

+363
-360
lines changed

UPGRADE-0.5.md

Lines changed: 362 additions & 0 deletions
B41A
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,362 @@
1+
# Upgrading from 0.4.x to 0.5
2+
3+
The dependent framework-agnostic package has a number of changes. Below lists the changes you will need to make
4+
to your application. However, if you are also extending underlying package functionality you will also need to refer
5+
to the `v0.5` to `v0.6` upgrade notes here:
6+
[cloudcreativty/json-api Upgrade Notes](https://github.com/cloudcreativity/json-api/blob/master/UPGRADE.md)
7+
8+
## Config
9+
10+
Paging config is now defined on a per-API basis, so you need to move your paging config into your API namespace
11+
config in the `json-api.php` config file. We have updated the comment blocks to reflect this; you can find those
12+
in the `config/json-api.php` file within this package.
13+
14+
Before:
15+
16+
``` php
17+
return [
18+
'namespaces' => [
19+
'v1' => [
20+
'url-prefix' => '/api/v1',
21+
'supported-ext' => null,
22+
],
23+
],
24+
25+
// ...
26+
27+
'pagination' => [
28+
'params' => [
29+
'page' => null,
30+
'per-page' => null,
31+
],
32+
'meta' => [
33+
'key' => null,
34+
'current-page' => 'page',
35+
'per-page' => 'size',
36+
'first-item' => null,
37+
'last-item' => null,
38+
'total' => null,
39+
'last-page' => 'last',
40+
],
41+
]
42+
];
43+
```
44+
45+
After:
46+
47+
``` php
48+
return [
49+
'namespaces' => [
50+
'v1' => [
51+
'url-prefix' => '/api/v1',
52+
'supported-ext' => null,
53+
'paging' => [
54+
'page' => null,
55+
'per-page' => null,
56+
],
57+
'paging-meta' => [
58+
'current-page' => 'page',
59+
'per-page' => 'size',
60+
'first-item' => null,
61+
'last-item' => null,
62+
'total' => null,
63+
'last-page' => 'last',
64+
],
65+
],
66+
],
67+
];
68+
```
69+
70+
## Authorizers
71+
72+
### Abstract Authorizer
73+
74+
If you are extending the `AbstractAuthorizer` class and implementing your own constructor, you will need to
75+
inject an instance of `CloudCreativity\JsonApi\Contracts\Repositories\ErrorRepositoryInterface` into the parent
76+
constructor. This change means you can now add errors to the error collection on your authorizer using the string
77+
keys for error objects held within your `json-api-errors` config file. For example:
78+
79+
``` php
80+
public function canRead($record, EncodingParametersInterface $parameters)
81+
{
82+
if (!\Auth::check()) {
83+
$this->addError('access-denied');
84+
return false;
85+
}
86+
87+
return true;
88+
}
89+
```
90+
91+
Note that the recommended way to create error objects is via the error repository (which holds your error config)
92+
because it provides opportunities to add in translation etc of errors in the future.
93+
94+
You will also need to implement the `canModifyRelationship` method. This was previously implemented in the abstract
95+
class but the previous implementation no longer works because of the change below.
96+
97+
### Update Authorization
98+
99+
Update authorization can now access the resource sent by the client. At the point the authorizer is invoked, the
100+
resource will have been validated to check that it complies with the JSON API spec but it will **not** have been
101+
checked that it is valid according to your business logic - i.e. attributes and relationships will not have
102+
been validated against the specific rules for that resource type.
103+
104+
Change the `canUpdate` method from this:
105+
106+
``` php
107+
canUpdate($record, EncodingParametersInterface $parameters)
108+
```
109+
110+
to:
111+
112+
``` php
113+
// CloudCreativity\JsonApi\Contracts\Object\ResourceInterface;
114+
canUpdate(
115+
$record,
116+
ResourceInterface $recource,
117+
EncodingParametersInterface $parameters
118+
)
119+
```
120+
121+
### Modify Relationship Authorization
122+
123+
Relationship modification authroization can now access the relationship sent by the client, as per the update
124+
authorization changes above.
125+
126+
Change the `canModifyRelationship` method from this:
127+
128+
``` php
129+
public function canModifyRelationship(
130+
$relationshipKey,
131+
$record,
132+
EncodingParametersInterface $parameters
133+
)
134+
```
135+
136+
to:
137+
138+
``` php
139+
// CloudCreativity\JsonApi\Contracts\Object\RelationshipInterface
140+
public function canModifyRelationship(
141+
$relationshipKey,
142+
$record,
143+
RelationshipInterface $relationship,
144+
EncodingParametersInterface $parameters
145+
)
146+
```
147+
148+
## Controllers
149+
150+
### Request Handler
151+
152+
The request class is no longer injected into the parent constructor. This change was necessary to support Laravel 5.3.
153+
Instead you now need to implement the `getRequestHandler` method and return a string of the fully qualified class
154+
name of the handler that is to be used. If you were not calling the parent constructor, you must now call it.
155+
156+
For example in an Eloquent controller, this:
157+
158+
``` php
159+
public function __construct(
160+
Posts\Request $request,
161+
Posts\Hydrator $hydrator,
162+
Posts\Search $search
163+
) {
164+
parent::__construct(new Post(), $request, $hydrator, $search);
165+
}
166+
```
167+
168+
Must be changed to:
169+
170+
``` php
171+
public function __construct(Posts\Hydrator $hydrator, Posts\Search $search)
172+
{
173+
parent::__construct(new Post(), $hydrator, $search);
174+
}
175+
176+
protected function getRequestHandler()
177+
{
178+
return Posts\Request::class;
179+
}
180+
```
181+
182+
### Action Methods
183+
184+
The method signature of all the action methods have changed - they now all receive the validated JSON API request
185+
object as they first argument.
186+
187+
For example, this:
188+
189+
``` php
190+
public function read($resourceId) {}
191+
```
192+
193+
Has become this:
194+
195+
``` php
196+
use CloudCreativity\JsonApi\Contracts\Http\Requests\RequestInterface as JsonApiRequest;
197+
// ...
198+
public function read(JsonApiRequest $request) {}
199+
```
200+
201+
Use the request object to get the resource id, relationship name and document (the JSON API request content). Refer
202+
to the interface for methods available.
203+
204+
### Eloquent Hooks
205+
206+
The `saving`, `saved`, `creating`, `created`, `updating`, `updated` method hooks now receive the resource provided
207+
by the client as the second method argument. (This object passed implements
208+
`CloudCreativity\JsonApi\Contracts\Object\ResourceInterface`.)
209+
210+
In addition, these methods are no longer implemented in the parent class. This means you can use whatever method
211+
signature you want, including type-hinting the first argument as the specific class of model that is being handled by
212+
the controller.
213+
214+
### Search All
215+
216+
You now need to always inject a search object into the Eloquent controller, otherwise the controller will return a
217+
`501 Not Implemented` response for the index action.
218+
219+
Previously the controller would list all models and would allow a find-many request (i.e. the client providing
220+
a list of ids as the `id` filter). If you have not written your own search class for the model being handled by
221+
your controller and want to maintain the previous behaviour, inject a `SearchAll` instance via your constructor:
222+
223+
``` php
224+
use CloudCreativity\LaravelJsonApi\Search\SearchAll;
225+
226+
public function __construct(SearchAll $search)
227+
{
228+
parent::__construct(new Post(), null, $search);
229+
}
230+
```
231+
232+
## Hydrators
233+
234+
The namespace of the `AbstractHydrator` has changed from `CloudCreativity\LaravelJsonApi\Hydrator\AbstractHydrator`
235+
to `CloudCreativity\JsonApi\Hydrator\AbstractHydrator`.
236+
237+
## Requests
238+
239+
Class `CloudCreativity\LaravelJsonApi\Http\Requests\AbstractRequest` has been removed. Instead you should extend
240+
`CloudCreativity\JsonApi\Http\Requests\RequestHandler`.
241+
242+
Note that the constructor for this new class has the authorizer as the first argument and the validators as the
243+
second (i.e. it is the other way round from what it was before). We've made this change because authorization
244+
occurs before validation, so it makes more sense for the arguments to be this way round.
245+
246+
## Responses (Reply Trait)
247+
248+
The method signature for the `errors` method has changed. To maintain the old behaviour use `error` instead (it
249+
accepts an error collection as well as a single error).
250+
251+
## Schemas
252+
253+
The JSON API specification recommends using hyphens for member names, e.g. `foo-bar`. The Eloquent schema now uses
254+
this recommendation as its default behaviour. E.g. a model key of `foo_bar` will be serialized as `foo-bar`.
255+
256+
To maintain the old behaviour (of using the model key for the member key), set the `$hyphenated` property on your
257+
schema to `false`. If you want to implement your own logic, overload the `keyForAttribute` method.
258+
259+
If you have irregular mappings of model keys to attribute keys, you can define these in your `$attributes` property,
260+
e.g.
261+
262+
``` php
263+
protected $attributes = [
264+
'foo',
265+
'bar',
266+
'foo_bar' // will be dasherized to 'foo-bar' by default
267+
'baz' => 'bat' // model key `baz` will be serialized to attribute key `bat`
268+
];
269+
```
270+
271+
## Search
272+
273+
We've merged the abstract sorted search class into the abstract search class, to simplify things.
274+
275+
You'll need to change:
276+
277+
``` php
278+
use CloudCreativity\LaravelJsonApi\Search\AbstractSortedSearch;
279+
280+
class Search extends AbstractSortedSearch
281+
{
282+
}
283+
```
284+
285+
to:
286+
287+
``` php
288+
use CloudCreativity\LaravelJsonApi\Search\AbstractSearch;
289+
290+
class Search extends AbstractSearch
291+
{
292+
}
293+
```
294+
295+
### Constructor
296+
297+
If you are overloading the constructor, you will need to call the parent constructor and provide it with the
298+
following two dependencies:
299+
300+
```
301+
CloudCreativity\JsonApi\Contracts\Http\HttpServiceInterface
302+
CloudCreativity\JsonApi\Contracts\Pagination\PaginatorInterface
303+
```
304+
305+
### Sort Parameter Field Conversion
306+
307+
When working out what column to use for a sort parameter, the sort parameter will automatically be snake cased if
308+
your model uses snake attributes. If it does not use snake attributes, the parameter will be camel cased.
309+
310+
If you have irregular mappings of search params to column names, add that mapping to your `$sortColumns` property,
311+
e.g. `$sortColumns = ['foo-bar' => 'baz_bat']`.
312+
313+
If you want to use a completely different logic for converting search params to column names, overload the
314+
`columnForField()` method.
315+
316+
## Validator Providers
317+
318+
The classes that provide validators for individual resource types generally extend `AbstractValidatorProvider`. This
319+
now receives the resource type that is being validated into its public methods, and this is now passed down through
320+
the internal methods. You'll therefore need to make the changes described below.
321+
322+
This change has been made so that a single validator provider can be used for multiple resource types if desired.
323+
Although you are likely to keep a validator provider per resource type (because attribute and relationship rules will
324+
be specific to a resource type), this has given us the capability to implement a generic validator provider capable of
325+
validating any resource type according to the JSON API spec.
326+
327+
### Constructor
328+
329+
If you have implemented a constructor, you will need to type hint the following interface and pass it to the parent
330+
constructor:
331+
332+
```
333+
CloudCreativity\LaravelJsonApi\Contracts\Validators\ValidatorFactoryInterface
334+
```
335+
336+
### Resource Type Property
337+
338+
You can remove the `$resourceType` property as it is no longer required.
339+
340+
### Method Changes
341+
342+
You'll need to adjust the signature of the following abstract methods, from:
343+
344+
``` php
345+
attributeRules($record = null)
346+
relationshipRules(RelationshipsValidatorInterface $relationships, $record = null)
347+
filterRules()
348+
```
349+
350+
to:
351+
352+
``` php
353+
attributeRules($resourceType, $record = null)
354+
relationshipRules(RelationshipsValidatorInterface $relationships, $resourceType, $record = null)
355+
filterRules($resourceType)
356+
```
357+
358+
The `filterRules` method is actually no longer abstract, so if you are returning an empty array from it you can delete
359+
it.
360+
361+
The signatures of other `protected` methods have also changed to pass down this additional argument. If you have
362+
implemented any other methods, check the abstract class for the new argument order.

0 commit comments

Comments
 (0)
0