|
1 | 1 | # Upgrade Guide |
2 | 2 |
|
3 | | -## 3.x to 4.0 |
| 3 | +## 4.x to 5.0 |
4 | 4 |
|
5 | | -To upgrade, run the following Composer commands: |
| 5 | +### Background |
6 | 6 |
|
7 | | -```bash |
8 | | -composer remove cloudcreativity/json-api-testing --dev |
9 | | -composer require cloudcreativity/laravel-json-api:^4.0 --no-update |
10 | | -composer require laravel-json-api/testing:^1.1 --dev --no-update |
11 | | -composer up cloudcreativity/* laravel-json-api/* |
12 | | -``` |
13 | | - |
14 | | -### PHP 8.1 |
15 | | - |
16 | | -To remove deprecation messages from PHP 8.1, we've added return types or `#[\ReturnTypeWillChange]` annotations to |
17 | | -methods for internal interfaces. This is unlikely to break your application, unless you have extended one of our classes |
18 | | -and overridden an internal method. |
19 | | - |
20 | | -### Testing |
| 7 | +This major release upgrades the underlying `neomerx/json-api` dependency from `v1` to `v5` of our fork, |
| 8 | +`laravel-json-api/neomerx-json-api`. |
21 | 9 |
|
22 | | -We are switching to using the `laravel-json-api/testing` package. This will help in the future with upgrading to the |
23 | | -new `laravel-json-api/laravel` package, because it will mean when you upgrade your tests should continue to work |
24 | | -without modifications. I.e. having a great test suite for your JSON:API functionality will help you safely upgrade in |
25 | | -the future. |
| 10 | +Upgrading this dependency means that both this package (`cloudcreativity/laravel-json-api`) and the newer package |
| 11 | +(`laravel-json-api/laravel`) now use the same version of the Neomerx encoder. This means applications can now install |
| 12 | +both this package and the newer package, unlocking an upgrade path between the two. While you cannot have an API that |
| 13 | +mixes the two packages, an application could now have an older API running off the old package, and a newer API |
| 14 | +implemented with the new package. Overtime you can deprecate the older API and eventually remove it - removing |
| 15 | +`cloudcreativity/laravel-json-api` in the process. |
26 | 16 |
|
27 | | -The `laravel-json-api/testing` dependency uses the `cloudcreativity/json-api-testing` package, which is what you have |
28 | | -been using up until now. It's just a more recent version, so there are a few changes to implement when upgrading. |
| 17 | +In case you're not aware, the Neomerx dependency is the package that does the encoding of classes to the JSON:API |
| 18 | +formatting. The problem we have always had with `cloudcreativity/laravel-json-api` is the package is too tightly |
| 19 | +coupled to the Neomerx implementation. This means this upgrade is a major internal change. While we have tested the |
| 20 | +upgrade to the best of our ability, if you find problems with it then please report them as issues on Github. |
29 | 21 |
|
30 | | -The new testing package is fully |
31 | | -[documented on the Laravel JSON:API site](https://laraveljsonapi.io/docs/1.0/testing/) so we recommend you take a look |
32 | | -at that if you get stuck when upgrading. |
| 22 | +While the new package (`laravel-json-api/laravel`) does use the Neomerx encoder, the use of that encoder is hidden |
| 23 | +behind generic interfaces. This fixed the problems with coupling and was one of the main motivations in building the |
| 24 | +new package. |
33 | 25 |
|
34 | | -#### Test Case |
| 26 | +### Upgrading |
35 | 27 |
|
36 | | -In the test case where you're importing `MakesJsonApiRequests`, change the `use` statement from this: |
| 28 | +To upgrade, run the following Composer command: |
37 | 29 |
|
38 | | -```php |
39 | | -use CloudCreativity\LaravelJsonApi\Testing\MakesJsonApiRequests; |
40 | | -``` |
41 | | - |
42 | | -to this: |
43 | | - |
44 | | -```php |
45 | | -use LaravelJsonApi\Testing\MakesJsonApiRequests; |
| 30 | +```bash |
| 31 | +composer require cloudcreativity/laravel-json-api:5.0.0-alpha.1 |
46 | 32 | ``` |
47 | 33 |
|
48 | | -#### Test Response |
49 | | - |
50 | | -If anywhere in your application you have type-hinted our specific `TestResponse` you will need to change the `use` |
51 | | -statement. (Note that most applications won't have type-hinted the `TestResponse` anywhere.) |
52 | | - |
53 | | -Previously: |
| 34 | +We've documented the changes that most applications will need to make below. However, if your application has made any |
| 35 | +changes to the implementation, e.g. by overriding elements of our implementation or using any of the Neomerx classes |
| 36 | +directly, there may be additional changes to make. If you're unsure how to upgrade anything, create a Github issue. |
| 37 | + |
| 38 | +### Import and Type-Hint Renaming |
| 39 | + |
| 40 | +Most of the upgrade can be completed by doing a search and replace for import statements and type-hints. |
| 41 | + |
| 42 | +Your application will definitely be using the following import statements that must be replaced: |
| 43 | + |
| 44 | +- `Neomerx\JsonApi\Contracts\Encoder\Parameters\EncodingParametersInterface` replace with |
| 45 | + `CloudCreativity\LaravelJsonApi\Contracts\Http\Query\QueryParametersInterface` |
| 46 | +- `Neomerx\JsonApi\Encoder\Parameters\EncodingParameters` replace with |
| 47 | + `CloudCreativity\LaravelJsonApi\Http\Query\QueryParameters` |
| 48 | +- `Neomerx\JsonApi\Schema\SchemaProvider` replace with |
| 49 | + `CloudCreativity\LaravelJsonApi\Schema\SchemaProvider` |
| 50 | + |
| 51 | +And it will also definitely be using these type-hints, that must be replaced: |
| 52 | + |
| 53 | +- `EncodingParametersInterface` with `QueryParametersInterface` |
| 54 | +- `EncodingParameters` with `QueryParameters` |
| 55 | + |
| 56 | +The following import statements also need changing, however you should not worry if you cannot find any usages of them |
| 57 | +within your application: |
| 58 | + |
| 59 | +- `Neomerx\JsonApi\Contracts\Encoder\Parameters\SortParameterInterface` replace with |
| 60 | + `CloudCreativity\LaravelJsonApi\Contracts\Http\Query\SortParameterInterface` |
| 61 | +- `Neomerx\JsonApi\Encoder\Parameters\SortParameter` replace with |
| 62 | + `CloudCreativity\LaravelJsonApi\Http\Query\SortParameter` |
| 63 | +- `Neomerx\JsonApi\Contracts\Document\ErrorInterface` replace with |
| 64 | + `Neomerx\JsonApi\Contracts\Schema\ErrorInterface` |
| 65 | +- `Neomerx\JsonApi\Document\Error` replace with |
| 66 | + `Neomerx\JsonApi\Schema\Error` |
| 67 | +- `Neomerx\JsonApi\Exceptions\ErrorCollection` replace with |
| 68 | + `Neomerx\JsonApi\Schema\ErrorCollection` |
| 69 | +- `Neomerx\JsonApi\Contracts\Document\LinkInterface` replace with |
| 70 | + `Neomerx\JsonApi\Contracts\Schema\LinkInterface` |
| 71 | +- `Neomerx\JsonApi\Contracts\Document\DocumentInterface` replace with |
| 72 | + `Neomerx\JsonApi\Contracts\Schema\DocumentInterface` |
| 73 | +- `Neomerx\JsonApi\Contracts\Http\Headers\HeaderInterface` replace with |
| 74 | + `CloudCreativity\LaravelJsonApi\Contracts\Http\Headers\HeaderInterface` |
| 75 | +- `Neomerx\JsonApi\Contracts\Http\Headers\AcceptHeaderInterface` replace with |
| 76 | + `CloudCreativity\LaravelJsonApi\Contracts\Http\Headers\AcceptHeaderInterface` |
| 77 | +- `Neomerx\JsonApi\Contracts\Http\Headers\HeaderParametersParserInterface` replace with |
| 78 | + `CloudCreativity\LaravelJsonApi\Contracts\Http\Headers\HeaderParametersParserInterface` |
| 79 | +- `Neomerx\JsonApi\Contracts\Http\Query\QueryParametersParserInterface` replace with |
| 80 | + `CloudCreativity\LaravelJsonApi\Contracts\Http\Query\QueryParametersParserInterface` |
| 81 | + |
| 82 | +### Schemas |
| 83 | + |
| 84 | +We have added argument and return type-hints to all methods on the schema class. You will need to add these to all your |
| 85 | +schemas. For example the `getId()`, `getAttributes()` and `getRelationships()` methods now look like this: |
54 | 86 |
|
55 | 87 | ```php |
56 | | -use CloudCreativity\LaravelJsonApi\Testing\TestResponse; |
57 | | -``` |
| 88 | +public function getId(object $resource): string {} |
58 | 89 |
|
59 | | -It now needs to be: |
| 90 | +public function getAttributes(object $resource): array {} |
60 | 91 |
|
61 | | -```php |
62 | | -use LaravelJsonApi\Testing\TestResponse; |
| 92 | +public function getRelationships(object $resource, bool $isPrimary, array $includeRelationships): array {} |
63 | 93 | ``` |
64 | 94 |
|
65 | | -#### Test Actions |
| 95 | +In addition, properties also now have type-hints. For example, you need to add a `string` type-hint to the |
| 96 | +`$resourceType` property. |
66 | 97 |
|
67 | | -The following test actions have been deprecated for some time and have now been removed. This is because these helper |
68 | | -methods used the JSON:API implementation internally, which was potentially risky as the JSON:API implementation itself |
69 | | -is the subject of the tests. These are the methods: |
70 | | - |
71 | | -- `doSearch()` |
72 | | -- `doSearchById()` |
73 | | -- `doCreate()` |
74 | | -- `doRead()` |
75 | | -- `doUpdate()` |
76 | | -- `doDelete()` |
77 | | -- `doReadRelated()` |
78 | | -- `doReadRelationship()` |
79 | | -- `doReplaceRelationship()` |
80 | | -- `doAddToRelationship()` |
81 | | -- `doRemoveFromRelationship()` |
82 | | - |
83 | | -Here are example replacements: |
| 98 | +Optionally, you can remove the `getId()` method from model schemas if the content of the method looks like this: |
84 | 99 |
|
85 | 100 | ```php |
86 | | -// doSearch() |
87 | | -$response = $this->jsonApi('posts')->get('/api/v1/posts'); |
88 | | - |
89 | | -// doSearchById() |
90 | | -$response = $this |
91 | | - ->jsonApi('posts') |
92 | | - ->filter(['id' => $posts]) |
93 | | - ->get('/api/v1/posts'); |
94 | | - |
95 | | -// doCreate() |
96 | | -$response = $this |
97 | | - ->jsonApi('posts') |
98 | | - ->withData($data) |
99 | | - ->post('/api/v1/posts'); |
100 | | - |
101 | | -// doRead() |
102 | | -$response = $this |
103 | | - ->jsonApi('posts') |
104 | | - ->get(url('/api/v1/posts', $post)); |
105 | | - |
106 | | -// doUpdate() |
107 | | -$response = $this |
108 | | - ->jsonApi('posts') |
109 | | - ->withData($data) |
110 | | - ->patch(url('/api/v1/posts', $post)); |
111 | | - |
112 | | -// doDelete() |
113 | | -$response = $this |
114 | | - ->jsonApi('posts') |
115 | | - ->delete(url('/api/v1/posts', $post)); |
116 | | - |
117 | | -// doReadRelated() |
118 | | -$response = $this |
119 | | - ->jsonApi('comments') |
120 | | - ->get(url('/api/v1/posts', [$post, 'comments'])); |
121 | | - |
122 | | -// doReadRelationship() |
123 | | -$response = $this |
124 | | - ->jsonApi('comments') |
125 | | - ->get(url('/api/v1/posts', [$post, 'relationships', 'comments'])); |
126 | | - |
127 | | -// doReplaceRelationship() |
128 | | -$response = $this |
129 | | - ->jsonApi('comments') |
130 | | - ->withData($data) |
131 | | - ->patch(url('/api/v1/posts', [$post, 'relationships', 'comments'])); |
132 | | - |
133 | | -// doAddToRelationship() |
134 | | -$response = $this |
135 | | - ->jsonApi('comments') |
136 | | - ->withData($data) |
137 | | - ->post(url('/api/v1/posts', [$post, 'relationships', 'comments'])); |
138 | | - |
139 | | -// doRemoveFromRelationship() |
140 | | -$response = $this |
141 | | - ->jsonApi('comments') |
142 | | - ->withData($data) |
143 | | - ->delete(url('/api/v1/posts', [$post, 'relationships', 'comments'])); |
144 | | -``` |
145 | | - |
146 | | -> Note in all the above we use `withData()` to set the data for the request. Previously there was a `data` method, which |
147 | | -> has been removed. |
148 | | -
|
149 | | -Also, the following HTTP verb JSON:API methods have been removed: |
150 | | - |
151 | | -- `getJsonApi` - use `$this->jsonApi('posts')->get($url)` |
152 | | -- `postJsonApi` - use `$this->jsonApi('posts')->withData($data)->post($url)` |
153 | | -- `patchJsonApi` - use `$this->jsonApi('posts')->withData($data)->patch($url)` |
154 | | -- `deleteJsonApi` - use `$this->jsonApi('posts')->withData($data)->delete($url)` |
155 | | - |
156 | | -> For info, everything has been moved to the test builder that's returned by the `jsonApi()` method, so that we can |
157 | | -> avoid collisions with any methods that Laravel might. |
158 | | -
|
159 | | -## 2.x to 3.0 |
160 | | - |
161 | | -### Validators |
162 | | - |
163 | | -The method signature of the `rules()` method has changed so that the method has access to the data |
164 | | -that is going to be validated. You will need to amend the method signature on all of your validator |
165 | | -classes. |
166 | | - |
167 | | -The method signature was previously: |
168 | | - |
169 | | -``` |
170 | | -protected function rules($record = null): array |
| 101 | +public function getId(object $resource): string |
171 | 102 | { |
172 | | - // ... |
| 103 | + return (string) $resource->getRouteKey(); |
173 | 104 | } |
174 | 105 | ``` |
175 | 106 |
|
176 | | -It is now: |
177 | | - |
178 | | -``` |
179 | | -protected function rules($record, array $data): array |
180 | | -{ |
181 | | - // ... |
182 | | -} |
183 | | -``` |
184 | | - |
185 | | -> Note that `$record` will still be `null` if the request will create a new resource. |
186 | | -
|
187 | | -### Soft Deletes |
188 | | - |
189 | | -Previously if no soft deletes field was set on an adapter, the JSON API field would default to the dash-case |
190 | | -version of the soft deletes column on the model. For example, if the model used the column `deleted_at`, |
191 | | -the JSON API field would default to `deleted-at`. |
192 | | - |
193 | | -In `v3`, the default is now the camel-case version of the column: i.e. `deleted_at` on the model would default |
194 | | -to `deletedAt` for the JSON API field. This change has been made because the JSON API spec has changed its |
195 | | -recommendation from using dash-case to camel-case. |
196 | | - |
197 | | -If you have existing resources that use dash-case, simply set the `softDeleteField` property on your adapter, |
198 | | -for example: |
199 | | - |
200 | | -```php |
201 | | -use CloudCreativity\LaravelJsonApi\Eloquent\AbstractAdapter; |
202 | | -use CloudCreativity\LaravelJsonApi\Eloquent\Concerns\SoftDeletesModels; |
203 | | - |
204 | | -class Adapter extends AbstractAdapter |
205 | | -{ |
206 | | - |
207 | | - use SoftDeletesModels; |
208 | | - |
209 | | - protected $softDeleteField = 'deleted-at'; |
210 | | - |
211 | | -} |
212 | | -``` |
213 | | - |
214 | | -## 1.x to 2.0 |
215 | | - |
216 | | -Version 2 drops support for all 5.x and 6.x versions of Laravel, and sets the minimum PHP version to 7.2. |
217 | | -This is because Laravel 7 introduced a few changes (primarily to the exception handler and the namespace |
218 | | -of the test response class) that meant it was not possible to support Laravel 6 and 7. |
219 | | - |
220 | | -This release is primarily a tidy-up release: we have removed all functionality that has been marked |
221 | | -as deprecated since the 1.0 pre-releases. Upgrading should be simple if you are not using any of the |
222 | | -deprecated pre-release features. |
223 | | - |
224 | | -The following are some notes on additional upgrade steps. |
225 | | - |
226 | 107 | ### Errors |
227 | 108 |
|
228 | | -If you were type-hinting our error class, it has been moved from `Document\Error` to `Document\Error\Error`. |
229 | | -In addition, the `Validation\ErrorTranslator` class has been moved to `Document\Error\Translator`. |
230 | | - |
231 | | -This will only affect applications that have customised error responses. |
232 | | - |
233 | | -### Testing |
234 | | - |
235 | | -The method signature of the test `jsonApi()` helper method on the `MakesJsonApiRequests` trait has been changed. |
236 | | -This now accepts no function arguments and returns a test builder instance that allows you to fluidly construct test |
237 | | -requests. |
238 | | - |
239 | | -For example this on your test case: |
240 | | - |
241 | | -```php |
242 | | -$response = $this->jsonApi('GET', '/api/v1/posts', ['include' => 'author']); |
243 | | -``` |
244 | | - |
245 | | -Is now: |
246 | | - |
247 | | -```php |
248 | | -$response = $this |
249 | | - ->jsonApi() |
250 | | - ->includePaths('author') |
251 | | - ->get('/api/v1/posts'); |
252 | | -``` |
253 | | - |
254 | | -> Have a look at the `Testing/TestBuilder` class for the full list of methods you can use when building |
255 | | -> a test request. |
256 | | -
|
257 | | -All other test methods have been left on the `MakesJsonApiRequests` have been left, but we have marked a number |
258 | | -as deprecated. These deprecated methods will be removed in 3.0 in preference of using method chaining from the |
259 | | -`jsonApi()` method. |
260 | | - |
261 | | -#### Test Query Parameters |
262 | | - |
263 | | -As per [this issue](https://github.com/cloudcreativity/laravel-json-api/issues/427), we now fail a test if |
264 | | -any query parameters values are not strings, integers or floats. This is because query parameters are received |
265 | | -over HTTP as strings, so for example testing a `true` boolean is invalid and can lead to tests incorrectly |
266 | | -passing. |
| 109 | +Check whether you are using the Neomerx error object directly anywhere, by searching for the new import statement: |
| 110 | +`Neomerx\JsonApi\Schema\Error`. If you are, you should be aware that the constructor arguments have changed. Check |
| 111 | +your use against the new constructor arguments by inspecting the class directly. |
0 commit comments