laravel-api-kit maintained by m-hidayatullahh
company/laravel-api-kit
Standardized API response envelope + global exception handling for Laravel 10 & 11, PHP 8.1+.
One install gives every backend project the same success/error/validation/pagination shape, so the frontend writes one set of handlers instead of many.
Install
Private repo via composer.json:
{
"repositories": [
{ "type": "vcs", "url": "git@github.com:company/laravel-api-kit.git" }
]
}
composer require company/laravel-api-kit
php artisan vendor:publish --tag=api-kit-config # optional
php artisan vendor:publish --tag=api-kit-lang # optional
The ServiceProvider and ApiResponse facade auto-register (package discovery).
Response shapes
Success:
{ "success": true, "message": "Data berhasil diambil", "data": {} }
Validation error (422):
{ "success": false, "message": "Validation failed", "errors": { "email": ["Email wajib diisi"] } }
Server error (500): { "success": false, "message": "Terjadi kesalahan pada server" }
Unauthorized (401): { "success": false, "message": "Unauthorized" }
Not found (404): { "success": false, "message": "Data tidak ditemukan" }
Usage
use Company\ApiKit\Facades\ApiResponse;
return ApiResponse::success($user, 'Data berhasil diambil');
return ApiResponse::error('Gagal memproses', 400);
return ApiResponse::validation(['email' => ['Email wajib diisi']]);
return ApiResponse::unauthorized();
return ApiResponse::forbidden();
return ApiResponse::notFound();
return ApiResponse::paginate(User::paginate());
Or via the controller trait:
use Company\ApiKit\Traits\HasApiResponse;
class UserController extends Controller
{
use HasApiResponse;
public function index()
{
return $this->respondPaginated(User::paginate());
}
}
Throwing for business rules (no try/catch needed — the renderer formats it):
use Company\ApiKit\Exceptions\BusinessException;
throw new BusinessException('Saldo tidak mencukupi', status: 422);
Wiring global exception handling
Laravel 11 — bootstrap/app.php
use Company\ApiKit\ApiKit;
->withExceptions(function (Illuminate\Foundation\Configuration\Exceptions $exceptions) {
ApiKit::handleExceptions($exceptions);
})
Laravel 10 — app/Exceptions/Handler.php
use Company\ApiKit\Exceptions\Concerns\InteractsWithApiExceptions;
class Handler extends ExceptionHandler
{
use InteractsWithApiExceptions;
public function register(): void
{
$this->renderApiExceptions();
}
}
Configuration highlights
api_prefix— which routes get standardized JSON errors (defaultapi).include_code— add a machine-readablecode(e.g.VALIDATION_FAILED) to error bodies.keys— rename envelope keys for incremental legacy migration.logging— 5xx are logged by default; 4xx are not.- Messages live in publishable lang files (
id,en). Setapp.localeor edit after publish.
Testing
composer install
composer test
Built with Pest + Orchestra Testbench.