jooservices/laravel-controller
| Install | |
|---|---|
composer require jooservices/laravel-controller |
|
| Latest Version: | v4.0.1 |
| PHP: | >=8.5 |
| Laravel: | 12 · 13 |
| Older releases: | 10 · 11 |
| License: | MIT |
| Last Updated: | Oct 19, 2026 |
| Links: | GitHub · Packagist |
jooservices/laravel-controller
JOOservices Laravel Controller is a Laravel API controller foundation for standardized JSON response envelopes, RFC 7807 Problem Details, OpenAPI envelope schemas, pagination metadata, status endpoints, trace IDs, and formatter-based response customization.
Composer package: jooservices/laravel-controller — current line: v4.0.1. Upgrading from v1.x: see UPGRADE-4.0.md.
Features
- base API controller helpers for success, error, validation, status, and no-content responses
- optional RFC 7807 Problem Details (
application/problem+json) via profile orrespondWithProblem() - stable OpenAPI 3.1 envelope schemas (
resources/openapi/envelope.v4.yaml) - Laravel
JsonResourceandResourceCollectionfriendly response helpers - standardized response envelope with configurable keys
- length-aware, simple, cursor, and offset pagination helpers (
meta.pagination) - echo of Idempotency-Key / rate-limit / Retry-After headers into
meta(no storage) - trace ID support through a configurable request header
- optional status endpoint with pluggable
StatusHealthCheckprobes - custom
ResponseFormattercontract for teams that need a different top-level JSON shape - optional exception response helper for common Laravel exceptions
- read-only
php artisan laravel-controller:doctordiagnostics
Requirements
- PHP
^8.5 - Laravel 12 or 13 (
illuminate/*^12.0or^13.0)
Installation
composer require jooservices/laravel-controller:^4.0
Publish Configuration
php artisan vendor:publish --provider="JOOservices\LaravelController\Providers\LaravelControllerServiceProvider" --tag="config"
Optional translations:
php artisan vendor:publish --provider="JOOservices\LaravelController\Providers\LaravelControllerServiceProvider" --tag="laravel-controller-lang"
Quick start
Use the package at the controller boundary. Keep request validation, business logic, and persistence in your application layers:
<?php
namespace App\Http\Controllers\Api\V1;
use App\Http\Requests\UserIndexRequest;
use App\Http\Resources\UserResource;
use App\Services\UserService;
use Illuminate\Http\JsonResponse;
use JOOservices\LaravelController\Http\Controllers\BaseApiController;
final class UserController extends BaseApiController
{
public function index(UserIndexRequest $request, UserService $users): JsonResponse
{
return $this->respondWithPagination(
paginator: $users->paginate($request->validated()),
resourceClass: UserResource::class,
message: 'Users retrieved successfully.',
);
}
}
Standard Architecture Usage
Recommended flow:
Request -> Controller -> FormRequest -> Service -> Repository -> Model
Model / entity / data object -> Laravel Resource -> API response envelope -> JsonResponse
Laravel Resource remains the presentation transformer. JOOservices Laravel Controller wraps the transformed payload in the API response envelope.
Response Envelope Example
{
"success": true,
"code": 200,
"message": "Users retrieved successfully.",
"data": [],
"meta": {},
"errors": null,
"trace_id": "550e8400-e29b-41d4-a716-446655440000"
}
Resource Example
public function show(UserShowRequest $request, UserService $users): JsonResponse
{
return $this->respondWithResource(
resource: new UserResource($users->findForDisplay($request->validated('id'))),
message: 'User retrieved successfully.',
);
}
DTOs, Arrayable, JsonSerializable, and objects with toArray() may be accepted as input data, but they do not replace Laravel Resources as the presentation layer.
Pagination Example
public function index(UserIndexRequest $request, UserService $users): JsonResponse
{
return $this->respondWithPagination(
paginator: $users->paginate($request->validated()),
resourceClass: UserResource::class,
message: 'Users retrieved successfully.',
);
}
Cursor and offset helpers nest fields under meta.pagination. You may pass a Laravel CursorPaginator directly to respondWithCursorPagination().
Error Response Example
public function archive(UserArchiveRequest $request, UserService $users): JsonResponse
{
if (! $users->canArchive($request->validated('id'))) {
return $this->respondWithError(
message: 'User cannot be archived.',
code: 409,
errors: ['user' => ['The user has active dependencies.']],
);
}
$users->archive($request->validated('id'));
return $this->respondNoContent();
}
For Problem Details, see docs/02-user-guide/problem-details.md or set response_profile to problem+json.
Status Endpoint
When package routes are enabled, the status endpoint is available under the configured prefix.
Without health checks it is a liveness probe (HTTP 200). With status.checks configured it acts as readiness: any failed check returns HTTP 503 and status: unavailable.
Built-in checks: database, cache, queue. Custom checks: class-strings implementing StatusHealthCheck.
GET /api/v1/status
Run diagnostics from the CLI:
php artisan laravel-controller:doctor
php artisan laravel-controller:doctor --json
Custom Formatter
<?php
namespace App\Support;
use JOOservices\LaravelController\Contracts\ResponseFormatter;
final class ApiResponseFormatter implements ResponseFormatter
{
public function format(array $response): array
{
return [
'ok' => $response['success'],
'status' => $response['code'],
'message' => $response['message'],
'payload' => $response['data'],
'error' => $response['errors'],
'request_id' => $response['trace_id'],
];
}
}
Configuration
Important config keys:
response_profile(envelope|problem+json)response_formatterkeysmeta_headerstrace_id.headeruse_translationssuccess_codesvalidation.messageroutes.enabledroutes.prefixroutes.auto_map_host_routesstatus(including pluggable checks)pagination_linksitem_links
Design notes
Scope and limitations
This package is:
- base API controller helpers
- standard response envelope helpers
- pagination and status response helpers
- OpenAPI envelope schema artifact
- formatter contract
- optional exception response helper
This package is not:
- CRUD generator
- service layer replacement
- repository replacement
- validation package
- full application exception-handler framework
- JSON:API full implementation
- idempotency store or rate-limit enforcer (headers are echoed only)
- business logic layer
Documentation
- Documentation Hub
- Changelog
- Upgrade to v4
- Workflows
- Architecture
- Getting Started
- User Guide
- Problem Details
- OpenAPI Contract
- Examples
- Development
- Release Process
- Maintenance
AI contributor support
Development
composer lint
composer lint:fix
composer test
composer test:coverage
composer coverage:check
composer check
composer ci
Prefer Docker (docker compose run --rm php …) when host PHP is not 8.5.
Community
License
JOOservices Laravel Controller is open-sourced software licensed under the MIT license.
Related Packages
PHP 8.5+ Laravel repository package for trait-based CRUD, filtering, ordering, a...
MongoDB-backed application configuration store for Laravel with typed access and...
This package is for handling the crud for simple crud like for setup etc.
Version History
| Version | Released | PHP | Laravel | License |
|---|---|---|---|---|
| v4.0.1 | >=8.5 | ^12.0| | MIT | |
| v4.0.0 | >=8.5 | ^12.0| | MIT | |
| v1.4.1 | ^8.5 | ^12.0| | MIT | |
| v1.4.0 | ^8.5 | ^12.0 | MIT | |
| v1.3.0 | ^8.5 | ^12.0 | MIT | |
| 1.2.0 | ^8.5 | ^12.0 | MIT | |
| 1.1.0 | ^8.5 | ^12.0 | MIT | |
| 1.0.0 | ^8.5 | ^10.0| | MIT |