From e04a70daa6c15a9d3e615ae3aab3c0fb6294d107 Mon Sep 17 00:00:00 2001 From: Huiren Woo Date: Thu, 29 Jun 2017 00:51:30 +0800 Subject: [PATCH 1/5] Fix password checking --- docs/custom-controller.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/custom-controller.md b/docs/custom-controller.md index ae58d2c9..4bed082d 100644 --- a/docs/custom-controller.md +++ b/docs/custom-controller.md @@ -110,8 +110,9 @@ The following are examples covering these functions. Do take note that you will $resource = $request->getDocument()->getResource(); $this->hydrator->hydrate($resource, $record); // Check if password has changed - if ($old_password !== $record->password) { - $record->password = Hash::make($record->password); + $new_password = $resource->getAttributes()->get('password'); + if (!Hash::check($new_password, $old_password)) { + $record->password = Hash::make($new_password); } $record->save(); return $this->reply()->content($record); From e7b51ebceec1086f2d908b9041b3a2a98bedf77d Mon Sep 17 00:00:00 2001 From: Huiren Woo Date: Thu, 29 Jun 2017 00:54:54 +0800 Subject: [PATCH 2/5] Add read related resource & read relationship --- docs/custom-controller.md | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/docs/custom-controller.md b/docs/custom-controller.md index 4bed082d..074d58ea 100644 --- a/docs/custom-controller.md +++ b/docs/custom-controller.md @@ -41,7 +41,7 @@ class UsersController extends Controller ## Structure -As mentioned before, there are mainly five functions: `index()`, `create()`, `read()`, `update()`, `delete()`. They are able to accept a few parameters and must make use of the reply trait to return a response. +As mentioned before, there are mainly five functions: `index()`, `create()`, `read()`, `update()`, `delete()`. There are also other functions that are listed below. They are able to accept a few parameters and must make use of the reply trait to return a response. The following are examples covering these functions. Do take note that you will need to import the namespaces correctly. @@ -133,3 +133,38 @@ The following are examples covering these functions. Do take note that you will return $this->reply()->noContent(); } ``` + +### Read Related Resource +If you link one resource to another through relationship, you'll need this to read the related resource. + +```php + /** + * @param JsonApiRequest $request + * @return mixed + */ + public function readRelatedResource(JsonApiRequest $request) + { + $model = $request->getRecord(); + $key = $request->getRelationshipName(); + return $this + ->reply() + ->content($model->{$key}); + } +``` + +### Read Relationship +This is for reading the relationship between two resources. +```php + /** + * @param JsonApiRequest $request + * @return mixed + */ + public function readRelationship(JsonApiRequest $request) + { + $model = $request->getRecord(); + $key = $request->getRelationshipName(); + return $this + ->reply() + ->relationship($model->{$key}); + } +``` From a44428b8cd9d4e032f61521eaa250df50beff670 Mon Sep 17 00:00:00 2001 From: Huiren Woo Date: Thu, 29 Jun 2017 01:28:12 +0800 Subject: [PATCH 3/5] Remove old custom controller docs --- docs/custom-controller.md | 170 -------------------------------------- 1 file changed, 170 deletions(-) delete mode 100644 docs/custom-controller.md diff --git a/docs/custom-controller.md b/docs/custom-controller.md deleted file mode 100644 index 074d58ea..00000000 --- a/docs/custom-controller.md +++ /dev/null @@ -1,170 +0,0 @@ -# Custom Controllers - -Sometimes, we might need to customize what happens within a controller and still be able to make full use of this package. - -## ReplyTrait - -In order to customize the controller's responses, we must first include the `use ReplyTrait` in the controller. - -```php -namespace App\Http\Controllers\Api; - -use App\JsonApi\Users; -use App\User; -use CloudCreativity\JsonApi\Contracts\Http\ApiInterface; -use CloudCreativity\JsonApi\Contracts\Http\Requests\RequestInterface as JsonApiRequest; -use CloudCreativity\LaravelJsonApi\Http\Responses\ReplyTrait; -use Illuminate\Support\Facades\Hash; -use Illuminate\Support\Facades\DB; -use Illuminate\Routing\Controller; - -class UsersController extends Controller -{ - use ReplyTrait; - - /** - * @var Users\Hydrator - */ - private $hydrator; - - /** - * UsersController constructor. - * - * @param Users\Hydrator $hydrator - */ - public function __construct(Users\Hydrator $hydrator) - { - $this->hydrator = $hydrator; - } -} -``` - -## Structure - -As mentioned before, there are mainly five functions: `index()`, `create()`, `read()`, `update()`, `delete()`. There are also other functions that are listed below. They are able to accept a few parameters and must make use of the reply trait to return a response. - -The following are examples covering these functions. Do take note that you will need to import the namespaces correctly. - -### Index - -```php - /** - * @param ApiInterface $api - * @param JsonApiRequest $request - * @return mixed - */ - public function index(ApiInterface $api, JsonApiRequest $request) - { - $store = $api->getStore(); - return $this->reply()->content($store->query( - $request->getResourceType(), - $request->getParameters() - )); - } -``` - -### Create - -```php - /** - * @param JsonApiRequest $request - * @return mixed - */ - public function create(JsonApiRequest $request) - { - $resource = $request->getDocument()->getResource(); - $record = null; - // Add custom DB transaction & password hashing - DB::transaction(function () use (&$resource, &$request, &$record) { - $record = new User; - $this->hydrator->hydrate($request->getDocument()->getResource(), $record); - $record->password = Hash::make($record->password); - $record->save(); - }); - return $this->reply()->created($record); - } -``` - -### Read -```php - /** - * @param JsonApiRequest $request - * @return mixed - */ - public function read(JsonApiRequest $request) - { - return $this->reply()->content($request->getRecord()); - } -``` -### Update -```php - /** - * @param JsonApiRequest $request - * @return mixed - */ - public function update(JsonApiRequest $request) - { - /** @var User $record */ - $record = $request->getRecord(); - $old_password = $record->password; - $resource = $request->getDocument()->getResource(); - $this->hydrator->hydrate($resource, $record); - // Check if password has changed - $new_password = $resource->getAttributes()->get('password'); - if (!Hash::check($new_password, $old_password)) { - $record->password = Hash::make($new_password); - } - $record->save(); - return $this->reply()->content($record); - } -``` - -### Delete -```php - /** - * @param JsonApiRequest $request - * @return mixed - */ - public function delete(JsonApiRequest $request) - { - /** @var User $record */ - $record = $request->getRecord(); - $record->delete(); - return $this->reply()->noContent(); - } -``` - -### Read Related Resource -If you link one resource to another through relationship, you'll need this to read the related resource. - -```php - /** - * @param JsonApiRequest $request - * @return mixed - */ - public function readRelatedResource(JsonApiRequest $request) - { - $model = $request->getRecord(); - $key = $request->getRelationshipName(); - return $this - ->reply() - ->content($model->{$key}); - } -``` - -### Read Relationship -This is for reading the relationship between two resources. -```php - /** - * @param JsonApiRequest $request - * @return mixed - */ - public function readRelationship(JsonApiRequest $request) - { - $model = $request->getRecord(); - $key = $request->getRelationshipName(); - return $this - ->reply() - ->relationship($model->{$key}); - } -``` From bbb4699962322d6a5194aeca17be5eaf4250fc32 Mon Sep 17 00:00:00 2001 From: Huiren Woo Date: Sat, 14 Oct 2017 23:20:21 +0800 Subject: [PATCH 4/5] Add documentation for inclusion of related resources --- docs/features/inclusion.md | 162 +++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 docs/features/inclusion.md diff --git a/docs/features/inclusion.md b/docs/features/inclusion.md new file mode 100644 index 00000000..c5b38c7e --- /dev/null +++ b/docs/features/inclusion.md @@ -0,0 +1,162 @@ +# Inclusion + +## Introduction + +This package supports the specification of [JSON API Inclusion of Related Resources](http://jsonapi.org/format/1.0/#fetching-includes). This allows you to load all the data of the specified resources that is bounded by relationship. + +### Using Include Parameter + +Per the specification, the client is able to request for the inclusion of related resources through the following HTTP request: + +```http +GET /api/posts?include=comments HTTP/2.0 +Accept: application/vnd.api+json +``` + +However, by default, this package denies inclusion of related resources via parameter and would throw the follow error message. + +```json +{ + "errors": [ + { + "title": "Include paths should contain only allowed ones.", + "source": { + "parameter": "include" + } + } + ] +} + +``` + +To allow certain resources to be included using request parameters, it must be manually enabled through the resource's `Validators.php` file. + +```php +namespace App\JsonApiV1\Posts; + +class Validators extends AbstractValidatorProvider +{ + protected $allowedIncludePaths = [ + 'comments' + ]; + + /* Your code here ...*/ +} +``` + + +### Auto Inclusion + +It is possible to force the inclusion of certain related resources; displaying it even when the client did not specify the related resource in the include parameter. To enable the automatic inclusion of resources, edit the resource's `Schema.php` file. + +```php +namespace App\JsonApiV1\Posts; + +class Schema extends EloquentSchema +{ + + /* Your code here ...*/ + + public function getIncludePaths() + { + return [ + 'comments' + ]; + } +} +``` + +And when the client sends the following request: + +```http +GET /api/posts HTTP/2.0 +Accept: application/vnd.api+json +``` + +The response would look something like this: + +```json +{ + "data": [ + { + "type": "posts", + "id": "6118bf58-7374-4e9a-9843-d1b0e53ac0b9", + "attributes": { + "created-at": "2017-10-14T07:56:44+00:00", + "updated-at": "2017-10-14T07:56:44+00:00", + "title": "Bernadine McClure", + "description": "Provident recusandae est rem consequatur. Et alias ut culpa architecto eligendi et temporibus. Aliquam ipsa vitae mollitia totam fuga." + }, + "relationships": { + "comments": { + "data": [ + { + "type": "comments", + "id": "3813a5ba-3d7b-432d-aa0d-eb0c3bd4e1a1" + }, + { + "type": "comments", + "id": "bb3dd8a2-8678-480e-b477-87c8fddc5702" + } + ], + "meta": { + "total": 2 + }, + "links": { + "self": "http://localhost:8000/api/v1/posts/6118bf58-7374-4e9a-9843-d1b0e53ac0b9/relationships/comments", + "related": "http://localhost:8000/api/v1/posts/6118bf58-7374-4e9a-9843-d1b0e53ac0b9/comments" + } + } + }, + "links": { + "self": "http://localhost:8000/api/v1/posts/6118bf58-7374-4e9a-9843-d1b0e53ac0b9" + } + } + ], + "included": [ + { + "type": "comments", + "id": "3813a5ba-3d7b-432d-aa0d-eb0c3bd4e1a1", + "attributes": { + "created-at": "2017-10-14T09:47:09+00:00", + "updated-at": "2017-10-14T09:47:09+00:00", + "description": "Excellent post!" + }, + "relationships": { + "post": { + "data": { + "type": "posts", + "id": "6118bf58-7374-4e9a-9843-d1b0e53ac0b9" + }, + "links": { + "self": "http://localhost:8000/api/v1/comments/3813a5ba-3d7b-432d-aa0d-eb0c3bd4e1a1/relationships/post", + "related": "http://localhost:8000/api/v1/comments/3813a5ba-3d7b-432d-aa0d-eb0c3bd4e1a1/post" + } + } + } + }, + { + "type": "comments", + "id": "bb3dd8a2-8678-480e-b477-87c8fddc5702", + "attributes": { + "created-at": "2017-10-14T07:57:52+00:00", + "updated-at": "2017-10-14T07:57:52+00:00", + "description": "I really like your post!" + }, + "relationships": { + "post": { + "data": { + "type": "posts", + "id": "6118bf58-7374-4e9a-9843-d1b0e53ac0b9" + }, + "links": { + "self": "http://localhost:8000/api/v1/comments/bb3dd8a2-8678-480e-b477-87c8fddc5702/relationships/post", + "related": "http://localhost:8000/api/v1/comments/bb3dd8a2-8678-480e-b477-87c8fddc5702/post" + } + } + } + } + ] +} + +``` \ No newline at end of file From 20d7e8fd75f8a0eb7b81c10566b34d6e690b693f Mon Sep 17 00:00:00 2001 From: Huiren Woo Date: Sat, 14 Oct 2017 23:27:25 +0800 Subject: [PATCH 5/5] Add inclusion page to mkdocs --- mkdocs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/mkdocs.yml b/mkdocs.yml index 33054d22..d119a0ea 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -16,6 +16,7 @@ pages: - Non-Eloquent: - Controllers: custom/controllers.md - Digging Deeper: + - Inclusion: features/inclusion.md - Broadcasting: features/broadcasting.md - Helpers: features/helpers.md - HTTP Clients: features/http-clients.md