Responses
Basic usage
The api() helper (and the ApiResponse facade) resolve a fresh fluent builder every time you call them - safe to chain, never shared state between responses.
use Bhry98\LaravelApiResponse\Facades\ApiResponse;
return api()
->success()
->message('User created.')
->data($user)
->send();
// identical, via the facade
return ApiResponse::success()->message('User created.')->data($user)->send();
ResponseBuilder implements Laravel's Responsable contract, so you can skip ->send() entirely and return the builder directly from a controller or route closure:
return api()->created($user);
Default JSON shape:
{
"status": true,
"message": "User created.",
"data": { "id": 1 }
}
Ready-made responses
HTTP shortcuts
api()->ok($data); // 200
api()->created($user); // 201
api()->accepted(); // 202
api()->noContent(); // 204, empty body
api()->badRequest($msg, $errors); // 400
api()->unauthorized(); // 401
api()->forbidden(); // 403
api()->notFound(); // 404
api()->conflict(); // 409
api()->unprocessable($errors); // 422
api()->tooManyRequests(); // 429
api()->internal(); // 500
api()->serviceUnavailable(); // 503
Business shortcuts
api()->saved($model);
api()->updated($model);
api()->deleted();
api()->restored($model);
api()->archived($model);
api()->verified($user);
api()->registered($user); // 201
api()->loggedIn($user);
api()->loggedOut();
api()->passwordChanged();
api()->uploaded($file); // 201
api()->download($url);
api()->emailSent();
api()->otpSent();
Every shortcut accepts an optional message override (api()->updated('Custom message.')) and pulls its default from config('bhry98-api-response.messages') otherwise.
Advanced usage
return api()
->success()
->message('Order placed.')
->data($order)
->meta(['queue_position' => 4])
->links(['tracking' => route('orders.track', $order)])
->extra(['request_id' => (string) Str::uuid()])
->headers(['X-Order-Id' => $order->id])
->cookie(Cookie::create('last_order')->withValue($order->id))
->version('v2')
->send();
data()/from()- attach a payload (auto-detected, see below).meta()/links()- merge into themeta/linksblocks.errors()- merge into theerrorsblock (used automatically bybadRequest()/unprocessable()).extra()- merge extra keys into the top level of the envelope.headers()/cookie()/cookies()- attach to the finalJsonResponse.statusCode()- set any arbitrary HTTP status.preset()- pick a response shape for this call only (see Presets).version()- overrideconfig('bhry98-api-response.version')for this response.localize($key)- translate the current (or given) message through Laravel's translator.
Templates
Define reusable, named responses in config:
// config/bhry98-api-response.php
'responses' => [
'user_created' => [
'status' => true,
'message' => 'User created successfully.',
'code' => 201,
],
'invoice_paid' => [
'status' => true,
'message' => 'Invoice paid.',
'code' => 200,
],
],
return api()->template('user_created');
// override individual fields per call
return api()->template('user_created', ['data' => $user]);
Macros
Register your own reusable responses - ResponseBuilder (and therefore api()/ApiResponse) is fully Macroable:
use Bhry98\LaravelApiResponse\Facades\ApiResponse;
ApiResponse::macro('invoicePaid', function (Invoice $invoice) {
/** @var \Bhry98\LaravelApiResponse\Builder\ResponseBuilder $this */
return $this->success()->message('Invoice paid.')->data($invoice);
});
return api()->invoicePaid($invoice);
Automatic data detection
data() (and its aliases from(), resource(), resourceCollection(), paginate()) automatically normalize whatever you pass in:
return api()->from($user); // Eloquent model
return api()->from($users); // Collection
return api()->from(UserResource::make($user)); // JsonResource
return api()->from(UserResource::collection($users)); // ResourceCollection
return api()->from($paginator); // LengthAwarePaginator / CursorPaginator
return api()->from($invoiceDto); // any Arrayable DTO
return api()->from(['id' => 1]); // plain array - passed through untouched
Pagination and resource-collection meta/links are lifted into the envelope's top-level meta/links automatically.
Pagination
return api()->paginate($users);
{
"status": true,
"message": "Operation successful.",
"data": [ ... ],
"meta": { "current_page": 1, "last_page": 5, "per_page": 15, "total": 72, "from": 1, "to": 15 },
"links": { "first": "...", "last": "...", "prev": null, "next": "..." }
}
Works identically for CursorPaginator and for a ResourceCollection built on top of either paginator.
Resources
api()->resource(UserResource::make($user));
api()->resourceCollection(UserResource::collection($users));
Next
Customization covers the envelope shape, global metadata, rate limiting, audit logging, locale resolution, hooks/events and exception handling.