brainstud/json-api-resource
最新稳定版本:v4.3.1
Composer 安装命令:
composer require brainstud/json-api-resource
包简介
Build JSON:API compliant Laravel API resources
README 文档
README
Make your Laravel API JSON:API compliant with the Brainstud\JsonApi package.
Table of contents
- Installation
- Usage
- Relationships
- Resource depth
- Exception handler
- Example
- Deprecated
registermethod - Tweaking responses
- License
Installation
Require the package
composer require brainstud/json-api-resource
Usage
- Let your resource object extend from
JsonApiResourceinstead ofJsonResource. - Set the type of your resource as a string in
$this->type. - For each part of your resource, define the matching
to{resourcePart}method.
class Resource extends JsonApiResource { protected string $type = 'resources'; protected function toAttributes(Request $request): array { return [ 'field' => $this->resource->field, 'other_field' => $this->resource->other_field, ]; } protected function toRelationships(Request $request): array { return [ 'relation' => ['relationMethod', Relation::class], ]; } protected function toLinks(Request $request): array { return [ 'type_of_link' => ['href' => 'link'], ]; } protected function toMeta(Request $request): array { return [ 'meta' => 'data', ]; } }
Relationships
JSON:API: Includes
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.
Resource depth
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. In the following example we use a depth of 3:
public function show(ShowCourseRequest $request, Course $course) { $query = (new CoursesQueryBuilder)->find($course->id); return new CourseResource([$query, 3]); }
Which allows us to ask for an include nested 3 levels deep: /courses/{identifier}?include=content,content.answers,content.answers.feedback
Exception handler
This package contains an exception handler to render exceptions as JSON:API error messages.
Either use this handler directly by editing your app.php and registering this singleton
// app.php $app->singleton( Illuminate\Contracts\Debug\ExceptionHandler::class, \Brainstud\JsonApi\Handlers\JsonApiExceptionHandler::class );
Or register your own exception handler and delegate the render to the JsonApiExceptionHandler::render method.
// app.php $app->singleton( Illuminate\Contracts\Debug\ExceptionHandler::class, App\Exceptions\Handler::class ); // handler.php public function render($request, Throwable $exception) { if ($request->wantsJson()) { return (new JsonApiExceptionHandler($this->container))->render($request, $exception); } return parent::render($request, $exception); }
Return error response
There are multiple ways to return an error page
// Throw an exception that will be handled by the JsonApiExceptionHandler throw new UnprocessableEntityHttpException(); // Return a defined error response return (new UnprocessableEntityError)->response(); // Return a custom error response return ErrorResponse::make(new DefaultError( 'PROCESSING_ERROR', 'Could not save item', 'An error occurred during saving of the item' ), Response::HTTP_INTERNAL_SERVER_ERROR);
Example usage
// Course.php /** * @property int $id * @property string $title * @property string $description * @property Carbon $created_at * @property Collection $enrollments */ class Course extends Model { protected $fillable = [ 'title', 'description', ]; public function enrollments(): HasMany { return $this->hasMany(Enrollment::class); } } // CourseResource.php /** * @property Course $resource */ class CourseResource extends JsonApiResource { protected string $type = 'courses'; protected function toAttributes(Request $request): array { return [ 'title' => $this->resource->title, 'description' => $this->resource->description, 'created_at' => $this->resource->created_at->format('c'), ]; } protected function toRelationships(Request $request): array { return [ 'enrollments' => ['enrollments', EnrollmentResourceCollection::class], ]; } protected function toLinks(Request $request): array { return [ 'view' => ['href' => $this->resource->getShowUrl()], ]; } protected function toMeta(Request $request): array { return [ 'enrollments' => $this->resource->enrollments->count(), ]; } } // CoursesController.php class CoursesController { public function index(IndexCoursesRequest $request) { $query = (new CoursesQueryBuilder)->jsonPaginate(); return new CourseResourceCollection($query); } public function show(ShowCourseRequest $request, Course $course) { $query = (new CoursesQueryBuilder)->find($course->id); return new CourseResource($query); } }
Defining resources via the register method
In the previous version of the package, you would have to define the resource structure via a register method. This is still possible, but it is deprecated and will be removed in a later version.
To use this way of defining a resource, simply define a register method in your resource:
protected function register(): array { return [ 'id' => $this->resource->identifier, 'type' => 'object_type', 'attributes' => [ 'field' => $this->resource->field, 'other_field' => $this->resource->other_field, ], 'relationships' => [ 'items' => ['items', ItemsResourceCollection::class], 'item' => ['item', ItemResource::class], ], 'meta' => [ 'some_data' => 'some value', ], 'links' => [ 'some_key' => 'some link', ], ]; }
Tweak response
The register method doesn't have access to $request like toArray of JsonResource has.
If you want to manipulate the response based on the request this can be done by overriding the addToResponse method.
protected function addToResponse($request, $response): array { if ($this->requestWantsMeta($request, 'data') && ($data = $this->getData()) ) { $response['meta']['data'] = $data; } return $response; }
License
JsonApi is open-sourced software licensed under the MIT Licence
统计信息
- 总下载量: 4.98k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 1
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2022-03-30