Skip to content

Commit 0d3ee6e

Browse files
authored
Update readme documentation to new methods (#29)
1 parent d48d8e8 commit 0d3ee6e

1 file changed

Lines changed: 178 additions & 92 deletions

File tree

README.md

Lines changed: 178 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,143 @@
11
# JSON:API Resource for Laravel
2+
23
Make your Laravel API [JSON:API](https://jsonapi.org/) compliant with the `Brainstud\JsonApi` package.
34

5+
## Table of contents
6+
7+
- [Installation](#installation)
8+
- [Usage](#usage)
9+
- [Relationships](#relationships)
10+
- [Resource depth](#resource-depth)
11+
- [Exception handler](#exception-handler)
12+
- [Example](#example-usage)
13+
- [Deprecated `register` method](#defining-resources-via-the-register-method)
14+
- [Tweaking responses](#tweak-response)
15+
- [License](#license)
16+
17+
## Installation
18+
19+
Require the package
20+
21+
```bash
22+
composer require brainstud/json-api-resource
23+
```
24+
25+
## Usage
26+
27+
- Let your resource object extend from `JsonApiResource` instead of `JsonResource`.
28+
- Set the type of your resource as a string in `$this->type`.
29+
- For each part of your resource, define the matching `to{resourcePart}` method.
30+
31+
```php
32+
class Resource extends JsonApiResource
33+
{
34+
protected string $type = 'resources';
35+
36+
protected function toAttributes(Request $request): array
37+
{
38+
return [
39+
'field' => $this->resource->field,
40+
'other_field' => $this->resource->other_field,
41+
];
42+
}
43+
44+
protected function toRelationships(Request $request): array
45+
{
46+
return [
47+
'relation' => ['relationMethod', Relation::class],
48+
];
49+
}
50+
51+
protected function toLinks(Request $request): array
52+
{
53+
return [
54+
'type_of_link' => ['href' => 'link'],
55+
];
56+
}
57+
58+
protected function toMeta(Request $request): array
59+
{
60+
return [
61+
'meta' => 'data',
62+
];
63+
}
64+
}
65+
```
66+
67+
## Relationships
68+
69+
[JSON:API: Includes](https://jsonapi.org/format/#fetching-includes)
70+
For the relationships to be included they need to be loaded. This can be done by implementing a `?include` parameter or using [spatie/laravel-query-builder](https://spatie.be/docs/laravel-query-builder/v3/introduction).
71+
72+
## Resource depth
73+
74+
The resource depth has a default of 2. This can be changed by passing an array to the resource where the second item is the required resource depth.
75+
In the following example we use a depth of 3:
76+
77+
```php
78+
public function show(ShowCourseRequest $request, Course $course)
79+
{
80+
$query = (new CoursesQueryBuilder)->find($course->id);
81+
return new CourseResource([$query, 3]);
82+
}
83+
```
84+
85+
Which allows us to ask for an include nested 3 levels deep: `/courses/{identifier}?include=content,content.answers,content.answers.feedback`
86+
87+
## Exception handler
88+
89+
This package contains an exception handler to render exceptions as JSON:API error messages.
90+
Either use this handler directly by editing your `app.php` and registering this singleton
91+
92+
```php
93+
// app.php
94+
$app->singleton(
95+
Illuminate\Contracts\Debug\ExceptionHandler::class,
96+
\Brainstud\JsonApi\Handlers\JsonApiExceptionHandler::class
97+
);
98+
```
99+
100+
Or register your own exception handler and delegate the render to the `JsonApiExceptionHandler::render` method.
101+
102+
```php
103+
// app.php
104+
$app->singleton(
105+
Illuminate\Contracts\Debug\ExceptionHandler::class,
106+
App\Exceptions\Handler::class
107+
);
108+
109+
// handler.php
110+
public function render($request, Throwable $exception)
111+
{
112+
if ($request->wantsJson()) {
113+
return (new JsonApiExceptionHandler($this->container))->render($request, $exception);
114+
}
115+
116+
return parent::render($request, $exception);
117+
}
118+
```
119+
120+
### Return error response
121+
122+
There are multiple ways to return an error page
123+
124+
```php
125+
// Throw an exception that will be handled by the JsonApiExceptionHandler
126+
throw new UnprocessableEntityHttpException();
127+
128+
// Return a defined error response
129+
return (new UnprocessableEntityError)->response();
130+
131+
// Return a custom error response
132+
return ErrorResponse::make(new DefaultError(
133+
'PROCESSING_ERROR',
134+
'Could not save item',
135+
'An error occurred during saving of the item'
136+
), Response::HTTP_INTERNAL_SERVER_ERROR);
137+
```
138+
4139
## Example usage
140+
5141
```php
6142
// Course.php
7143

@@ -12,13 +148,13 @@ Make your Laravel API [JSON:API](https://jsonapi.org/) compliant with the `Brain
12148
* @property Carbon $created_at
13149
* @property Collection $enrollments
14150
*/
15-
class Course extends Model
151+
class Course extends Model
16152
{
17153
protected $fillable = [
18154
'title',
19155
'description',
20156
];
21-
157+
22158
public function enrollments(): HasMany
23159
{
24160
return $this->hasMany(Enrollment::class);
@@ -28,27 +164,44 @@ class Course extends Model
28164
// CourseResource.php
29165

30166
/**
31-
* @property Course $resource
167+
* @property Course $resource
32168
*/
33169
class CourseResource extends JsonApiResource
34170
{
35-
protected function register(): array
171+
protected string $type = 'courses';
172+
173+
protected function toAttributes(Request $request): array
36174
{
37175
return [
38-
'id' => $this->resource->id,
39-
'type' => 'courses',
40-
'attributes' => [
41-
'title' => $this->resource->title,
42-
'description' => $this->resource->description,
43-
'created_at' => $this->resource->created_at->format('c'),
44-
],
45-
'relationships' => [
46-
'enrollments' => ['enrollments', EnrollmentResourceCollection::class],
47-
],
176+
'title' => $this->resource->title,
177+
'description' => $this->resource->description,
178+
'created_at' => $this->resource->created_at->format('c'),
179+
];
180+
}
181+
182+
protected function toRelationships(Request $request): array
183+
{
184+
return [
185+
'enrollments' => ['enrollments', EnrollmentResourceCollection::class],
186+
];
187+
}
188+
189+
protected function toLinks(Request $request): array
190+
{
191+
return [
192+
'view' => ['href' => $this->resource->getShowUrl()],
193+
];
194+
}
195+
196+
protected function toMeta(Request $request): array
197+
{
198+
return [
199+
'enrollments' => $this->resource->enrollments->count(),
48200
];
49201
}
50202
}
51203

204+
52205
// CoursesController.php
53206

54207
class CoursesController
@@ -58,7 +211,7 @@ class CoursesController
58211
$query = (new CoursesQueryBuilder)->jsonPaginate();
59212
return new CourseResourceCollection($query);
60213
}
61-
214+
62215
public function show(ShowCourseRequest $request, Course $course)
63216
{
64217
$query = (new CoursesQueryBuilder)->find($course->id);
@@ -67,16 +220,12 @@ class CoursesController
67220
}
68221
```
69222

70-
## Installation
71-
Require the package
223+
## Defining resources via the `register` method
72224

73-
```bash
74-
composer require brainstud/json-api-resource
75-
```
225+
In the previous version of the package, you would have to define the resource structure via a register method.
226+
This is still possible, but it is **deprecated** and will be removed in a later version.
76227

77-
## Usage
78-
- Let your resource object extend from `JsonApiResource` instead of `JsonResource`.
79-
- Implement a `register` method that returns the following array. The register has access to `$this->resource` which contains the current model
228+
To use this way of defining a resource, simply define a `register` method in your resource:
80229

81230
```php
82231
protected function register(): array
@@ -93,17 +242,17 @@ protected function register(): array
93242
'item' => ['item', ItemResource::class],
94243
],
95244
'meta' => [
96-
'some_data' => 'some value',
245+
'some_data' => 'some value',
246+
],
247+
'links' => [
248+
'some_key' => 'some link',
97249
],
98250
];
99251
}
100252
```
101253

102-
## Relationships
103-
[JSON:API: Includes](https://jsonapi.org/format/#fetching-includes)
104-
For the relationships to be included they need to be loaded. This can be done by implementing a `?include` parameter or using [spatie/laravel-query-builder](https://spatie.be/docs/laravel-query-builder/v3/introduction).
105-
106254
## Tweak response
255+
107256
The `register` method doesn't have access to `$request` like `toArray` of `JsonResource` has.
108257
If you want to manipulate the response based on the request this can be done by overriding the `addToResponse` method.
109258

@@ -118,71 +267,8 @@ protected function addToResponse($request, $response): array
118267

119268
return $response;
120269
}
121-
````
122-
123-
## Resource depth
124-
The resource depth has a default of 2. This can be changed by passing an array to the resource where the second item is the required resource depth.
125-
In the following example we use a depth of 3:
126-
127-
```php
128-
public function show(ShowCourseRequest $request, Course $course)
129-
{
130-
$query = (new CoursesQueryBuilder)->find($course->id);
131-
return new CourseResource([$query, 3]);
132-
}
133-
```
134-
135-
Which allows us to ask for an include nested 3 levels deep: `/courses/{identifier}?include=content,content.answers,content.answers.feedback`
136-
137-
## Exception handler
138-
This package contains an exception handler to render exceptions as JSON:API error messages.
139-
Either use this handler directly by editing your `app.php` and registering this singleton
140-
141-
```php
142-
// app.php
143-
$app->singleton(
144-
Illuminate\Contracts\Debug\ExceptionHandler::class,
145-
\Brainstud\JsonApi\Handlers\JsonApiExceptionHandler::class
146-
);
147-
```
148-
149-
Or register your own exception handler and delegate the render to the `JsonApiExceptionHandler::render` method.
150-
151-
```php
152-
// app.php
153-
$app->singleton(
154-
Illuminate\Contracts\Debug\ExceptionHandler::class,
155-
App\Exceptions\Handler::class
156-
);
157-
158-
// handler.php
159-
public function render($request, Throwable $exception)
160-
{
161-
if ($request->wantsJson()) {
162-
return (new JsonApiExceptionHandler($this->container))->render($request, $exception);
163-
}
164-
165-
return parent::render($request, $exception);
166-
}
167-
```
168-
169-
### Return error response
170-
There are multiple ways to return an error page
171-
172-
```php
173-
// Throw an exception that will be handled by the JsonApiExceptionHandler
174-
throw new UnprocessableEntityHttpException();
175-
176-
// Return a defined error response
177-
return (new UnprocessableEntityError)->response();
178-
179-
// Return a custom error response
180-
return ErrorResponse::make(new DefaultError(
181-
'PROCESSING_ERROR',
182-
'Could not save item',
183-
'An error occurred during saving of the item'
184-
), Response::HTTP_INTERNAL_SERVER_ERROR);
185270
```
186271

187272
## License
273+
188274
JsonApi is open-sourced software licensed under the [MIT Licence](LICENSE)

0 commit comments

Comments
 (0)