|
| 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 | + |
B41A
| 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