Search by

jooservices / laravel-controller

jooservices

Laravel API controller foundation for standardized JSON envelopes, RFC 7807 Problem Details, OpenAPI schemas, pagination, status checks, and custom formatters.

Package info

github.com/jooservices/laravel-controller

pkg:composer/jooservices/laravel-controller

Statistics

Installs: 502

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v4.0.1 2026-09-05 16:19 UTC

README

CI codecov Quality gate status OpenSSF Scorecard PHP Version Release License: MIT Packagist Version

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 or respondWithProblem()
  • stable OpenAPI 3.1 envelope schemas (resources/openapi/envelope.v4.yaml)
  • Laravel JsonResource and ResourceCollection friendly 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 StatusHealthCheck probes
  • custom ResponseFormatter contract for teams that need a different top-level JSON shape
  • optional exception response helper for common Laravel exceptions
  • read-only php artisan laravel-controller:doctor diagnostics

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_formatter
  • keys
  • meta_headers
  • trace_id.header
  • use_translations
  • success_codes
  • validation.message
  • routes.enabled
  • routes.prefix
  • routes.auto_map_host_routes
  • status (including pluggable checks)
  • pagination_links
  • item_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

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.