raditzfarhan/laravel-api-response

Laravel API response formatter

Maintainers

Package info

github.com/raditzfarhan/laravel-api-response

Type:laravel-package

pkg:composer/raditzfarhan/laravel-api-response

Statistics

Installs: 3 718

Dependents: 1

Suggesters: 0

Stars: 4

Open Issues: 0

1.3.3 2026-04-11 02:47 UTC

This package is auto-updated.

Last update: 2026-04-11 02:48:08 UTC


README

Laravel API Response

Latest Stable Version Total Downloads License StyleCI

A fluent API response formatter for Laravel. Returns consistent JSON responses across your application with minimal boilerplate.

Requirements

  • PHP ^8.0
  • Laravel 9, 10, 11, 12 or 13

Installation

composer require raditzfarhan/laravel-api-response

The service provider is auto-discovered. No manual registration needed.

Basic Usage

Two styles are available — use whichever fits your preference:

// Via the response() helper macro (auto-registered)
return response()->api()->success();
return response()->api()->failed();

// Via the facade
return ApiResponse::success();
return ApiResponse::failed();

Both return an Illuminate\Http\JsonResponse instance.

Success response:

{
    "status": true,
    "http_code": 200,
    "message": "Success."
}

Failed response:

{
    "status": false,
    "http_code": 500,
    "message": "Failed."
}

Chaining

Build your response by chaining any combination of these methods before calling success() or failed():

Method Description
httpCode(int $code) Set the HTTP status code
message(string $message) Set the response message
data(mixed $data) Set the response data
errors(array $errors) Set validation/error details
meta(array $meta) Set metadata
links(array $links) Set pagination links
code(int|string $code) Set an application-level error/status code
headers(array $headers) Set custom HTTP response headers
return ApiResponse::httpCode(201)
    ->message('User created successfully.')
    ->data(['id' => 1, 'name' => 'Raditz Farhan'])
    ->success();
{
    "status": true,
    "http_code": 201,
    "message": "User created successfully.",
    "data": {
        "id": 1,
        "name": "Raditz Farhan"
    }
}

Application-Level Error Codes

Use code() to attach an application-specific error or status code alongside the HTTP status code:

return ApiResponse::code(40401)->notFound();
{
    "status": false,
    "http_code": 404,
    "code": 40401,
    "message": "Not found."
}

The code field only appears when set. Manage your own code definitions using constants or enums in your application.

Custom HTTP Headers

Use headers() to attach custom HTTP response headers. Headers are sent with the response but never appear in the JSON body:

return ApiResponse::headers([
    'X-Request-Id' => (string) Str::uuid(),
    'X-Version'    => '1.0',
])->success();

Shorthand Methods

Common HTTP responses have dedicated shorthand methods. All accept an optional $message parameter:

// 2xx
return ApiResponse::created($data);         // 201
return ApiResponse::collection($paginator); // 200 with meta & links

// 4xx
return ApiResponse::badRequest();           // 400
return ApiResponse::unauthorized();         // 401
return ApiResponse::forbidden();            // 403
return ApiResponse::notFound();             // 404
return ApiResponse::methodNotAllowed();     // 405
return ApiResponse::notAcceptable();        // 406
return ApiResponse::requestTimeout();       // 408
return ApiResponse::conflict();             // 409
return ApiResponse::gone();                 // 410
return ApiResponse::validationError();      // 422
return ApiResponse::tooManyRequests();      // 429

// 5xx
return ApiResponse::internalServerError();  // 500
return ApiResponse::notImplemented();       // 501
return ApiResponse::badGateway();           // 502
return ApiResponse::serviceUnavailable();   // 503
return ApiResponse::gatewayTimeout();       // 504

Pass a custom message to any of them:

return ApiResponse::conflict('A record with this email already exists.');

Validation Errors

return ApiResponse::validationError($validator->errors()->toArray());
{
    "status": false,
    "http_code": 422,
    "message": "Validation error.",
    "errors": {
        "email": ["The email field is required."]
    }
}

Paginated Collections

Pass a LengthAwarePaginator or AnonymousResourceCollection to collection():

return ApiResponse::collection(Post::paginate(25));
{
    "status": true,
    "http_code": 200,
    "message": "Success.",
    "data": [ ... ],
    "meta": {
        "current_page": 1,
        "last_page": 3,
        "from": 1,
        "to": 25,
        "per_page": 25,
        "total": 60,
        "has_more_pages": true
    },
    "links": {
        "first": "https://example.com/posts?page=1",
        "last": "https://example.com/posts?page=3",
        "prev": null,
        "next": "https://example.com/posts?page=2"
    }
}

Exception Handling

To ensure all API error responses — including Laravel's built-in exceptions — follow the same structure, register custom renderers in your exception handler.

Laravel 11+ (bootstrap/app.php):

use Illuminate\Auth\AuthenticationException;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use RaditzFarhan\ApiResponse\Facades\ApiResponse;

->withExceptions(function (Exceptions $exceptions) {
    $exceptions->render(function (ValidationException $e, Request $request) {
        if ($request->expectsJson()) {
            return ApiResponse::validationError($e->errors(), $e->getMessage());
        }
    });

    $exceptions->render(function (AuthenticationException $e, Request $request) {
        if ($request->expectsJson()) {
            return ApiResponse::unauthorized();
        }
    });

    $exceptions->render(function (NotFoundHttpException $e, Request $request) {
        if ($request->expectsJson()) {
            return ApiResponse::notFound();
        }
    });
})

Laravel 9 / 10 (app/Exceptions/Handler.php):

use Illuminate\Auth\AuthenticationException;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use RaditzFarhan\ApiResponse\Facades\ApiResponse;

public function register(): void
{
    $this->renderable(function (ValidationException $e, Request $request) {
        if ($request->expectsJson()) {
            return ApiResponse::validationError($e->errors(), $e->getMessage());
        }
    });

    $this->renderable(function (AuthenticationException $e, Request $request) {
        if ($request->expectsJson()) {
            return ApiResponse::unauthorized();
        }
    });

    $this->renderable(function (NotFoundHttpException $e, Request $request) {
        if ($request->expectsJson()) {
            return ApiResponse::notFound();
        }
    });
}

The $request->expectsJson() guard ensures non-API routes (web, Blade) are unaffected and still render the default HTML error pages.

Configuration

Publish the config file to customise key names and add global fields:

php artisan vendor:publish --provider="RaditzFarhan\ApiResponse\ApiResponseServiceProvider"

This creates config/laravel-api-response.php.

Rename Response Keys

Rename any of the default JSON keys globally without changing your application code:

'keys' => [
    'status'    => 'success',   // "status" → "success"
    'http_code' => 'code',      // "http_code" → "code"
    'message'   => 'message',
    'data'      => 'data',
    'errors'    => 'errors',
    'meta'      => 'meta',
    'links'     => 'links',
    'code'      => 'error_code',
],

Global Fields

Append fields to every response automatically. Supports static values and closures:

'global_fields' => [
    'version'    => '1.0',
    'request_id' => fn() => request()->header('X-Request-Id'),
],

Every response will then include:

{
    "status": true,
    "http_code": 200,
    "message": "Success.",
    "version": "1.0",
    "request_id": "abc-123"
}

IDE Support

All chainable and shorthand methods are annotated with @method PHPDoc on both the ApiResponse class and the facade, giving full autocomplete in PhpStorm, VS Code, and other IDEs.

Change log

Please see the changelog for more information on what has changed recently.

Credits

License

MIT. Please see the license file for more information.