gungcahyadipp/laravel-structured-response

Structured JSON API response package for Laravel

Maintainers

Package info

github.com/gungcahyadipp/Laravel-Structured-Response

pkg:composer/gungcahyadipp/laravel-structured-response

Statistics

Installs: 11

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-05-25 03:29 UTC

This package is auto-updated.

Last update: 2026-05-25 05:38:39 UTC


README

Tests License

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.