jooservices / laravel-controller
Laravel API controller foundation for standardized JSON envelopes, RFC 7807 Problem Details, OpenAPI schemas, pagination, status checks, and custom formatters.
Requires
- php: >=8.5
- illuminate/console: ^12.0|^13.0
- illuminate/http: ^12.0|^13.0
- illuminate/routing: ^12.0|^13.0
- illuminate/support: ^12.0|^13.0
Requires (Dev)
- captainhook/captainhook: ^5.23
- captainhook/plugin-composer: ^5.3
- fakerphp/faker: ^1.24
- friendsofphp/php-cs-fixer: ^3.65
- laravel/pint: ^1.18
- orchestra/testbench: ^10.0|^11.0
- phpmd/phpmd: ^2.15
- phpstan/phpstan: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- phpstan/phpstan-strict-rules: ^2.0
- phpunit/phpunit: ^12.0 || ^13.0
- squizlabs/php_codesniffer: ^3.8 || ^4.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-05 19:31:02 UTC
README
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
Installation
composer require jooservices/laravel-controller:^4.0
Publish Config
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
Current Limitations And Non-Goals
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
- Upgrade to v4
- Architecture
- Getting Started
- User Guide
- Problem Details
- OpenAPI Contract
- Examples
- Development
- Release Process
- Maintenance
AI Contributor Support
Development Commands
composer lint
composer lint:all
composer lint:fix
composer test
composer test:coverage
composer check
composer ci
Prefer Docker (docker compose run --rm php …) when host PHP is not 8.5.
Security And Contributing
Use GitHub issues for bug reports and security coordination unless a dedicated security policy is added. See CONTRIBUTING.md.
License
JOOservices Laravel Controller is open-sourced software licensed under the MIT license.