A professional Laravel package for standardized API responses with customizable keys and helper functions.
Install the package via Composer:
composer require rawnoq/laravel-api-responseThe package will automatically register its service provider.
- Standardized API Responses: Consistent JSON response structure across your application
- Customizable Keys: Configure response keys (status, data, message, etc.)
- Helper Function: Easy-to-use
respond()helper function - Pagination Support: Automatic pagination handling for paginated resources
- HTTP Status Codes: Pre-built methods for common HTTP status codes
- Flexible Messages: Support for single messages or arrays of messages
- Type-Safe: Full type hints and return types
use function respond;
// Success response
return respond()->success($data, 'Operation successful');
// Error response
return respond()->error('Something went wrong', null, 400);
// Custom response
return respond()->response($data, 'Custom message', 200, true, 'custom-action');The package provides a global respond() helper function:
// In your controller
public function index()
{
$users = User::all();
return respond()->success($users, 'Users retrieved successfully');
}
public function store(Request $request)
{
$user = User::create($request->validated());
return respond()->created($user, 'User created successfully');
}
public function show($id)
{
$user = User::findOrFail($id);
return respond()->ok('User retrieved successfully', $user);
}The package provides pre-built methods for common HTTP status codes:
// 200 OK
return respond()->ok('Operation successful', $data);
// 201 Created
return respond()->created($data, 'Resource created successfully');
// 202 Accepted
return respond()->accepted('Request accepted', $data);
// 204 No Content
return respond()->noContent('Resource deleted successfully');
// 400 Bad Request
return respond()->badRequest('Invalid request data');
// 401 Unauthorized
return respond()->unauthorized('Authentication required');
// 403 Forbidden
return respond()->forbidden('Access denied');
// 404 Not Found
return respond()->notFound('Resource not found');
// 409 Conflict
return respond()->conflict('Resource already exists');
// 422 Unprocessable Entity
return respond()->unprocessableEntity('Validation failed', $errors);
// 429 Too Many Requests
return respond()->tooManyRequests('Rate limit exceeded');
// 500 Internal Server Error
return respond()->internalServerError('An error occurred');
// 502 Bad Gateway
return respond()->badGateway('Bad gateway');
// 503 Service Unavailable
return respond()->serviceUnavailable('Service temporarily unavailable');
// 504 Gateway Timeout
return respond()->gatewayTimeout('Gateway timeout');The package automatically handles paginated resources:
public function index()
{
$users = User::paginate(15);
return respond()->success($users, 'Users retrieved successfully');
}This will automatically include pagination metadata in the response:
{
"status": true,
"code": 200,
"action": "success",
"message": "Users retrieved successfully",
"data": [...],
"pagination": {
"total": 100,
"per_page": 15,
"current_page": 1,
"last_page": 7,
"from": 1,
"to": 15,
"links": {
"current": "http://example.com/api/users?page=1",
"first": "http://example.com/api/users?page=1",
"last": "http://example.com/api/users?page=7",
"prev": null,
"next": "http://example.com/api/users?page=2"
}
}
}You can customize the response keys by creating a new instance with custom keys:
$respond = new \Rawnoq\ApiResponse\Support\Respond(
status_key: 'success',
enable_status_key: true,
data_key: 'payload',
message_key: 'msg',
messages_key: 'errors'
);
return $respond->success($data, 'Operation successful');Or use the helper function with configuration:
$respond = respond();
$respond->status_key = 'success';
$respond->data_key = 'payload';
$respond->message_key = 'msg';
return $respond->success($data, 'Operation successful');You can pass arrays of messages:
return respond()->error([
'Email is required',
'Password must be at least 8 characters'
], null, 422);This will include both message (first message) and messages (all messages) in the response:
{
"status": false,
"code": 422,
"action": "error",
"message": "Email is required",
"messages": [
"Email is required",
"Password must be at least 8 characters"
]
}Publish the configuration file:
php artisan vendor:publish --tag=api-response-configThis will create config/api-response.php:
return [
'status_key' => 'status',
'enable_status_key' => true,
'data_key' => 'data',
'message_key' => 'message',
'messages_key' => 'messages',
];{
"status": true,
"code": 200,
"action": "success",
"message": "Operation successful",
"data": {...}
}{
"status": false,
"code": 400,
"action": "error",
"message": "Something went wrong",
"data": null
}{
"status": true,
"code": 200,
"action": "success",
"message": "Data retrieved successfully",
"data": [...],
"pagination": {
"total": 100,
"per_page": 15,
"current_page": 1,
"last_page": 7,
"from": 1,
"to": 15,
"links": {
"current": "http://example.com/api/users?page=1",
"first": "http://example.com/api/users?page=1",
"last": "http://example.com/api/users?page=7",
"prev": null,
"next": "http://example.com/api/users?page=2"
}
}
}response($data, $message, $code, $status, $action)- Generic response methodsuccess($data, $message, $code, $status, $action)- Success response (200)error($message, $data, $code, $status, $action)- Error response (400)ok($message, $data, $code, $status, $action)- OK response (200)
created($data, $message, $code, $status, $action)- 201 Createdaccepted($message, $data, $code, $status, $action)- 202 AcceptednoContent($message, $code, $status, $action)- 204 No ContentbadRequest($message, $data, $code, $status, $action)- 400 Bad Requestunauthorized($message, $data, $code, $status, $action)- 401 Unauthorizedforbidden($message, $data, $code, $status, $action)- 403 ForbiddennotFound($message, $data, $code, $status, $action)- 404 Not FoundmethodNotAllowed($message, $data, $code, $status, $action)- 405 Method Not Allowedconflict($message, $data, $code, $status, $action)- 409 Conflictgone($message, $data, $code, $status, $action)- 410 GonelengthRequired($message, $data, $code, $status, $action)- 411 Length RequiredpreconditionFailed($message, $data, $code, $status, $action)- 412 Precondition FailedunprocessableEntity($message, $data, $code, $status, $action)- 422 Unprocessable EntitytooManyRequests($message, $data, $code, $status, $action)- 429 Too Many RequestsinternalServerError($message, $data, $code, $status, $action)- 500 Internal Server ErrorbadGateway($message, $data, $code, $status, $action)- 502 Bad GatewayserviceUnavailable($message, $data, $code, $status, $action)- 503 Service UnavailablegatewayTimeout($message, $data, $code, $status, $action)- 504 Gateway TimeoutnotImplemented($message, $data, $code, $status, $action)- 501 Not Implemented
<?php
namespace App\Http\Controllers;
use App\Http\Requests\StoreUserRequest;
use App\Models\User;
use Illuminate\Http\Request;
use function respond;
class UserController extends Controller
{
public function index()
{
$users = User::paginate(15);
return respond()->success($users, 'Users retrieved successfully');
}
public function store(StoreUserRequest $request)
{
$user = User::create($request->validated());
return respond()->created($user, 'User created successfully');
}
public function show($id)
{
$user = User::findOrFail($id);
return respond()->ok('User retrieved successfully', $user);
}
public function update(StoreUserRequest $request, $id)
{
$user = User::findOrFail($id);
$user->update($request->validated());
return respond()->ok('User updated successfully', $user);
}
public function destroy($id)
{
$user = User::findOrFail($id);
$user->delete();
return respond()->noContent('User deleted successfully');
}
}public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'email' => 'required|email',
'password' => 'required|min:8',
]);
if ($validator->fails()) {
return respond()->unprocessableEntity(
$validator->errors()->all(),
$validator->errors()
);
}
// ...
}public function custom()
{
$data = ['custom' => 'data'];
return respond()->response(
$data,
'Custom message',
200,
true,
'custom-action'
);
}- PHP >= 8.2
- Laravel >= 11.0 or Laravel >= 12.0
The package comes with a comprehensive test suite covering all functionality:
# Run tests
composer test
# Run tests with coverage
composer test-coverageThe test suite includes:
- ✅ 40+ test cases covering all response methods
- ✅ All HTTP status codes (200, 201, 400, 401, 403, 404, 422, 500, etc.)
- ✅ Custom response keys and configurations
- ✅ Pagination handling
- ✅ Array messages support
- ✅ ServiceProvider registration
- ✅ Helper function availability
- ✅ Edge cases (null data, null messages, disabled status key)
This package is open-sourced software licensed under the MIT license.
Contributions are welcome! Please feel free to submit a Pull Request.
For issues, questions, or suggestions, please open an issue on GitHub.