@@ -9,10 +9,85 @@ JSON should be *semantically* correct. E.g. when a client is providing a resourc
99` attributes ` member must be an object.
1010
1111This package provides framework agnostic validation of the received request body content - so that it can be handled
12- knowing that not only has ` json_decode ` successfully run, but that the structure of the decoded JSON is as expected.
13- Provided decoders also returns decoded content as ` StandardObject ` instances, an object that provides a number of
12+ knowing that not only has ` json_decode ` successfully run, but that the structure of the decoded JSON is as expected.
13+ Provided decoders also returns decoded content as ` StandardObject ` instances, an object that provides a number of
1414helper methods for handling the decoded content e.g. within a controller.
1515
16+ ## Let's see an example...
17+
18+ A common scenario would be to decode received input for a resource object and then attempt to access its supplied
19+ attributes within a controller. For example:
20+
21+ ``` php
22+ class ArticleController
23+ {
24+
25+ public function createAction()
26+ {
27+ $content = ... // get HTTP request body content.
28+ $data = json_decode($content, true);
29+ $attributes = $data['data']['attributes'];
30+ }
31+ }
32+ ```
33+
34+ This is unsafe because the controller is assuming that the decoded ` $data ` is an array, has a ` data ` key, which
35+ itself is an array with an ` attributes ` key. This cannot be assumed because a client request cannot be trusted.
36+
37+ Also, the JSON-API spec specifies certain errors that must be sent if the provided input for a create resource under
38+ certain scenarios - e.g.:
39+
40+ > A server MUST return ` 409 Conflict ` when processing a ` POST ` request in which the resource object's ` type ` is not among
41+ the type(s) that constitute the collection represented by the endpoint.
42+
43+ However, the controller has not checked whether ` $data['type'] ` exists or whether it is an expected type.
44+
45+ The above example can be refactored to use validators to parse the provided content before handling it within the
46+ controller:
47+
48+ ``` php
49+
50+ use CloudCreativity\JsonApi\Validator\Resource\ResourceObjectValidator;
51+ use CloudCreativity\JsonApi\Validator\Document\DocumentValidator;
52+ use CloudCreativity\JsonApi\Decoders\DocumentDecoder;
53+
54+ class ArticleController
55+ {
56+
57+ public function getArticleValidator()
58+ {
59+ $validator = new ResourceObjectValidator();
60+
61+ $validator->type('article')
62+ ->attr('title', 'string')
63+ ->attr('content', 'string')
64+ ->belongsTo('author', 'person')
65+ ->required(['author']);
66+
67+ return $validator;
68+ }
69+
70+ public function getDecoder()
71+ {
72+ $validator = new DocumentValidator($this->getArticleValidator());
73+ return new DocumentDecoder($validator);
74+ }
75+
76+ public function createAction()
77+ {
78+ $content = ... // get HTTP request body content.
79+ /** @var CloudCreativity\JsonApi\Object\Document\Document $data */
80+ $data = $this->getDecoder()->decode($content);
81+ $attributes = $data->getResourceObject()->getAttributes();
82+ }
83+ }
84+
85+ ```
86+
87+ In this refactored controller, ` $data ` can be used knowing that it has passed validation of the JSON API spec, and has
88+ been cast to an instance of ` CloudCreativity\JsonApi\Object\Document\Document ` , providing a fluid interface for
89+ handling the input within the controller.
90+
1691## Status
1792
1893This repository is under active development and is currently in a pre-release state.
0 commit comments