laravel-structured-response maintained by gungcahyadipp
Laravel Structured Response
Standar response JSON API untuk Laravel 10/11/12/13 dengan resource, relationship, pagination, includes, dan sparse fieldsets — tanpa dependensi yang tidak perlu.
Instalasi
composer require gungcahyadipp/laravel-structured-response
(Opsional) publish config:
php artisan vendor:publish --tag=structured-response-config
Quick start
use App\Http\Resources\UserResource;
return ok(UserResource::make($user));
return ok(UserResource::collection(User::paginate(15)));
return invalid($validator->errors());
return not_found('User not found');
Resource
use GungCahyadiPP\StructuredResponse\Http\Resources\JsonResource;
class UserResource extends JsonResource
{
public function type(): string
{
return 'users';
}
public function attributes(): array
{
return [
'name' => $this->name,
'email' => $this->email,
];
}
public function relationships(): array
{
return [
'posts' => PostResource::collection($this->whenLoaded('posts')),
];
}
}
Shorthand helpers
| Helper | Code | Use case |
|---|---|---|
ok($data, $message = '', $meta = []) |
200 | Success |
created($data, $message = '', $meta = []) |
201 | Resource created |
no_content() |
204 | Empty success |
error($message, $code = 500, $meta = []) |
* | Generic error |
invalid($errors, $message = 'Validation failed') |
422 | Validation |
not_found($message = 'Resource not found') |
404 | Missing resource |
unauthorized($message = 'Unauthenticated.') |
401 | Auth required |
forbidden($message = 'This action is unauthorized.') |
403 | Forbidden |
Fluent builder
return response_api()
->ok(UserResource::make($user))
->withMeta(['generated_at' => now()->toISOString()])
->send();
ResponseBuilder adalah immutable — setiap method mengembalikan instance baru.
Pagination
Cukup oper paginator (LengthAwarePaginator atau CursorPaginator). Meta pagination otomatis muncul di meta.pagination.
return ok(UserResource::collection(User::paginate(15)));
Includes
Mendukung ?include=posts.comments,company. Aktifkan via IncludeParser di config.
Sparse fieldsets
Mendukung ?fields[users]=name,email. Aktifkan via FieldsetParser di config.
Exception integration
Laravel 11+ (bootstrap/app.php):
->withExceptions(function (Exceptions $exceptions) {
$exceptions->render(
app(\GungCahyadiPP\StructuredResponse\Exceptions\ExceptionRenderer::class)->render(...)
);
})
Laravel 10 (app/Exceptions/Handler.php):
public function render($request, Throwable $e)
{
$rendered = app(ExceptionRenderer::class)->render($request, $e);
return $rendered ?? parent::render($request, $e);
}
Testing helper
use GungCahyadiPP\StructuredResponse\Testing\AssertableJsonResponse;
AssertableJsonResponse::from($response)
->assertResponseSuccess()
->assertResourceType('users')
->assertResourceCount(15)
->assertHasPagination();
Macros
use GungCahyadiPP\StructuredResponse\Support\ResponseBuilder;
ResponseBuilder::macro('accepted', fn () => $this->ok(null, 'Accepted'));
Compatibility
| Laravel | PHP | Testbench |
|---|---|---|
| 10.x | 8.2 | ^8.0 |
| 11.x | 8.2 / 8.3 | ^9.0 |
| 12.x | 8.3 | ^10.0 |
| 13.x | 8.3 / 8.4 | ^11.0 |
Development
composer install
vendor/bin/pest
vendor/bin/phpstan analyse
vendor/bin/php-cs-fixer check
License
MIT — see LICENSE.