Installation
composer require sm-sandy/api-response
Publish the config file (if needed):
php artisan vendor:publish --provider="SmSandy\ApiResponse\ApiResponseServiceProvider"
First Use Case Return a success response in a controller:
use SmSandy\ApiResponse\Facades\ApiResponse;
public function show($id)
{
$data = User::findOrFail($id);
return ApiResponse::success($data, 'User retrieved successfully');
}
Return an error response:
public function store(Request $request)
{
try {
// Logic here
} catch (\Exception $e) {
return ApiResponse::error('Validation failed', $e->getMessage());
}
}
Where to Look First
SmSandy\ApiResponse\Facades\ApiResponseconfig/api-response.php (for default messages)README.md for built-in methods like success(), error(), validationError(), etc.Consistent Response Structure Use the facade to enforce a uniform response format across all endpoints:
// Success with data
ApiResponse::success($user, 'User created', 201);
// Error without data
ApiResponse::error('Unauthorized', 'Invalid credentials', 401);
// Validation error
ApiResponse::validationError($validator->errors());
Dynamic Response Customization Override default messages or structure per endpoint:
ApiResponse::setSuccessMessage('Custom success message');
ApiResponse::setErrorMessage('Custom error message');
// Reset to defaults
ApiResponse::resetMessages();
Integration with Laravel Features
Resource classes for nested data:
return ApiResponse::success(new UserResource($user));
validationError() in handle():
public function handle()
{
$this->validate();
// ...
}
HandleIncomingRequest:
public function handle($request, Closure $next)
{
try {
return $next($request);
} catch (\Exception $e) {
return ApiResponse::error('Server error', $e->getMessage(), 500);
}
}
Batch Processing Return paginated or collection responses:
ApiResponse::success(User::paginate(10), 'Users list');
Custom Response Classes
Extend the base ApiResponse class for project-specific needs:
namespace App\Responses;
use SmSandy\ApiResponse\ApiResponse as BaseResponse;
class AppResponse extends BaseResponse
{
public function customSuccess($data, $message = null)
{
return $this->respond([
'status' => 'custom_success',
'data' => $data,
'message' => $message ?? 'Custom operation succeeded',
], 200);
}
}
Conditional Responses Dynamically choose response type based on logic:
if ($user->exists) {
return ApiResponse::success($user);
} else {
return ApiResponse::error('Not found', 'User does not exist', 404);
}
Localization Support Use Laravel’s localization with config:
// config/api-response.php
'messages' => [
'success' => [
'default' => 'lang::api.success.default',
],
],
Then translate in your language files (resources/lang/en/api.php).
Overriding Config Too Late
setSuccessMessage()) may not persist across requests if called after the response is sent.boot() method:
public function boot()
{
ApiResponse::setSuccessMessage(__('api.success.default'));
}
Nested Data Serialization
->toArray() or ->resolve() on Eloquent models:
ApiResponse::success($user->load('posts')->resolve());
Status Code Conflicts
200 for success) may clash with Laravel’s defaults.ApiResponse::success($data, 'Message', 200); // Force 200 OK
Facade vs. Class Instantiation
new ApiResponse) bypasses config.// Avoid this (unless extending)
$response = new \SmSandy\ApiResponse\ApiResponse();
Inspect Response Structure
Use dd() or dump() to verify the response format:
$response = ApiResponse::success($data);
dd($response->getData());
Check Config Overrides Verify published config isn’t being overridden:
php artisan config:clear
Log Custom Messages Add debug logs for custom responses:
\Log::debug('Custom response triggered', [
'data' => $data,
'message' => $message,
]);
Custom Response Macros Add reusable methods to the facade:
ApiResponse::macro('apiError', function ($message, $errors = null) {
return $this->error('API Error', $message, 400, $errors);
});
// Usage:
ApiResponse::apiError('Invalid input', $validator->errors());
Event-Based Responses Trigger responses via Laravel events:
// In EventServiceProvider
protected $listen = [
'user.created' => [\App\Listeners\HandleUserCreation::class],
];
// Listener
public function handle()
{
return ApiResponse::success('User created!');
}
Testing Helper Create a testing trait for consistent assertions:
trait AssertsApiResponse
{
protected function assertSuccessResponse($response, $data = null)
{
$response->assertJsonStructure([
'status' => 'success',
'data' => $data ? $data : [],
]);
}
}
Avoid Redundant Calls Cache repeated responses (e.g., for static errors):
$errorResponse = ApiResponse::error('Not found');
return $errorResponse; // Reuse
Lazy-Load Data Defer data loading until response is needed:
ApiResponse::success(function () use ($userId) {
return User::find($userId)->load('posts');
});
Disable for Non-API Routes Use middleware to skip formatting for non-API routes:
// app/Http/Kernel.php
'web' => [
\App\Http\Middleware\SkipApiResponse::class,
// ...
],
How can I help you explore Laravel packages today?