Skip to content

Commit

Permalink
[Feature] Add relationship hooks to the JSON API controller
Browse files Browse the repository at this point in the history
Closes #163
  • Loading branch information
lindyhopchris committed Apr 29, 2018
1 parent 174c997 commit fa15bc1
Show file tree
Hide file tree
Showing 8 changed files with 416 additions and 144 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ All notable changes to this project will be documented in this file. This projec
## Unreleased

### Added
- The Eloquent controller now has the following additional hooks:
- The JSON API controller now has the following additional hooks:
- `searching` for an *index* action.
- `reading` for a *read* action.
- [#163](https://github.com/cloudcreativity/laravel-json-api/issues/163)
Added relationship hooks to the JSON API controller.

### Changed
- Generating an Eloquent schema will now generate a class that extends `SchemaProvider`, i.e. the generic schema.
Expand Down
77 changes: 74 additions & 3 deletions docs/basics/controllers.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,22 @@ class PostsController extends JsonApiController
### Resource Hooks

The controller allows you to hook into resource lifecycle by invoking the following methods if they are implemented:
`searching`, `reading`, `creating`, `created`, `updating`, `updated`, `saving`, `saved`, `deleting`, `deleted`.
These methods allow you to easily implement authorization, trigger events and/or dispatch jobs as needed.
The controller allows you to hook into the resource lifecycle by invoking the following methods if they are
implemented:

- `searching`
- `reading`
- `saving`
- `creating`
- `updating`
- `created`
- `updated`
- `saved`
- `deleting`
- `deleted`

These methods allow you to easily implement application specific actions, such as firing events or dispatching
jobs.

The `searching` and `reading` hooks are invoked when resource(s) are being accessed, i.e. a `GET` request. The
`searching` hook is invoked when reading any resources (the *index* action), while `reading` is invoked when
Expand Down Expand Up @@ -153,6 +166,64 @@ class PostsController extends JsonApiController
}
```

### Relationship Hooks

The controller also allows you to hook into the relationship lifecycle by invoking the following methods if they are
implemented:

- `readingRelationship`
- `reading{Field}`
- `replacing`
- `replacing{Field}`
- `replaced{Field}`
- `replaced`
- `adding`
- `adding{Field}`
- `added{Field`
- `added`
- `removing`
- `removing{Field}`
- `removed{Field}`
- `removed`

These methods allow you to easily implement application specific actions, such as firing events or dispatching
jobs.

In the above method names `{Field}` refers to the camel-cased JSON API field name for the relationship. For example,
if reading the `author` relationship on a `posts` resource, the `readingRelationship` and/or `readingAuthor`
methods will be invoked if they exist.

The `reading...` methods are invoked when accessing the related resource or the relationship data, i.e. a `GET`
relationship request. The `replacing...` methods are invoked when changing the entire relationship in a
`PATCH` relationship request.

For *to-many* relationships, the `adding...` methods are invoked when adding resources to the relationship
using a `POST` relationship request. The `removing...` methods are invoked when removing resource from the
relationship using a `DELETE` relationship request.

All the relationship hooks receive the primary record being read as their first argument, and the JSON API request
received from the client as the second. For example:

```php
use App\Post;
use CloudCreativity\LaravelJsonApi\Http\Controllers\JsonApiController;
use CloudCreativity\LaravelJsonApi\Http\Requests\ValidatedRequest;

class PostsController extends JsonApiController
{

protected function replacing(Post $post, ValidatedRequest $request)
{
// ...
}

protected function addingTags(Post $post, ValidatedRequest $request)
{
// ...
}
}
```

### Responses

The standard controller returns responses for each controller action that comply with the JSON API specification
Expand Down
12 changes: 9 additions & 3 deletions src/Eloquent/HasMany.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,33 +91,37 @@ public function update($record, RelationshipInterface $relationship, EncodingPar
* @param Model $record
* @param RelationshipInterface $relationship
* @param EncodingParametersInterface $parameters
* @return void
* @return Model
*/
public function replace($record, RelationshipInterface $relationship, EncodingParametersInterface $parameters)
{
$this->update($record, $relationship, $parameters);
$record->refresh(); // in case the relationship has been cached.

return $record;
}

/**
* @param Model $record
* @param RelationshipInterface $relationship
* @param EncodingParametersInterface $parameters
* @return void
* @return Model
*/
public function add($record, RelationshipInterface $relationship, EncodingParametersInterface $parameters)
{
$related = $this->findRelated($record, $relationship);

$this->getWritableRelation($record)->saveMany($related);
$record->refresh(); // in case the relationship has been cached.

return $record;
}

/**
* @param Model $record
* @param RelationshipInterface $relationship
* @param EncodingParametersInterface $parameters
* @return void
* @return Model
*/
public function remove($record, RelationshipInterface $relationship, EncodingParametersInterface $parameters)
{
Expand All @@ -131,6 +135,8 @@ public function remove($record, RelationshipInterface $relationship, EncodingPar
}

$record->refresh(); // in case the relationship has been cached

return $record;
}

/**
Expand Down
2 changes: 2 additions & 0 deletions src/Eloquent/HasOne.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ public function replace($record, RelationshipInterface $relationship, EncodingPa
{
$this->update($record, $relationship, $parameters);
$record->refresh(); // in case the relationship has been cached.

return $record;
}

/**
Expand Down
Loading

0 comments on commit fa15bc1

Please sign in to comment.