PHPackages                             mmae/apiresponse - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. mmae/apiresponse

ActiveLibrary[API Development](/categories/api)

mmae/apiresponse
================

Standard API Response for Front-End Clients

v2.0.0(1mo ago)1318[1 issues](https://github.com/Mahmoud1478/MMAE-ApiResponse/issues)MITPHP

Since Jul 29Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/Mahmoud1478/MMAE-ApiResponse)[ Packagist](https://packagist.org/packages/mmae/apiresponse)[ RSS](/packages/mmae-apiresponse/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (2)Dependencies (9)Versions (4)Used By (0)

mmae/apiresponse
================

[](#mmaeapiresponse)

Standard JSON API response envelope for Laravel apps. Every response — success or failure — comes back in the same shape, so front-end clients parse one format.

Install
-------

[](#install)

```
composer require mmae/apiresponse
```

Service provider auto-registers via package discovery (`MMAE\ApiResponse\MMAEApiResponseServiceProvider`).

Response envelope
-----------------

[](#response-envelope)

```
{
  "success": true,
  "data": {},
  "errors": {},
  "message": "",
  "token": ""
}
```

`HasApiResponse` trait
----------------------

[](#hasapiresponse-trait)

`MMAE\ApiResponse\Traits\HasApiResponse` — add to any controller (or class) that needs to emit the envelope.

```
use MMAE\ApiResponse\Traits\HasApiResponse;

class UserController extends Controller
{
    use HasApiResponse;

    public function show(User $user)
    {
        return $this->successResponse(UserResource::make($user));
    }
}
```

Methods (all private, all return `JsonResponse`):

MethodPurposeStatus default`successResponse($data, $statusCode = 200)`success + data200`successResponseWithToken($data, $token, $message = '', $statusCode = 200)`success + data + token (e.g. login)200`successMessageResponse($message, $statusCode = 200)`success + message only, no data200`createdResponse($data, $message = '', $statusCode = 201)`success + data, resource created201`registeredSuccessfullyResponse($data, $token, $message = '', $statusCode = 201)`success + data + token, user registered201`updatedResponse($data, $message = '', $statusCode = 200)`success + data, resource updated200`deletedResponse($message = '', $statusCode = 200)`success + message only, resource deleted, no data200`failedResponse($errors, $message, $statusCode = null)`failure + errors`Response::$FAILED_STATUS` (400)`failedMessageResponse($message, $statusCode = null)`failure + message only`Response::$FAILED_STATUS` (400)`$data` accepts `array`, `Collection`, `JsonResource`, `LengthAwarePaginator`, or `Model`. All methods funnel through the private `makeResponse()`.

See [`examples/UserController.md`](examples/UserController.md) for a full CRUD + registration controller with real captured responses for every scenario (success, validation failure, not found, unhandled/broken code — `app.debug` on and off).

### Debugging: `dumpAndDie()`

[](#debugging-dumpanddie)

`HasApiResponse::dumpAndDie(JsonResponse $response)` — private helper, pretty-prints a `JsonResponse` envelope to stdout and halts execution (`exit`). API-only: no HTML VarDumper output, just the JSON. Not currently called by any of the public response methods above — invoke it directly on a built response when you need to inspect the exact envelope during development.

### Rendering exceptions: `exceptionResponse()` and per-exception builders

[](#rendering-exceptions-exceptionresponse-and-per-exception-builders)

`HasApiResponse::exceptionResponse(Throwable $exception, ?Request $request = null): JsonResponse` — renders any caught `Throwable` into the envelope. Exceptions implementing `MMAE\ApiResponse\Contracts\ExceptionContract` (the 4 exceptions below) render themselves; anything else is wrapped in `GeneralErrorException` (original preserved as `$previous`, subject to the [debug mode](#debug-mode-raw-message--trace) rules) and reported to the app's exception handler via `report()`. `$request` defaults to the current request when omitted.

```
public function show(string $id)
{
    try {
        return $this->successResponse(UserResource::make(User::findOrFail($id)));
    } catch (Throwable $e) {
        return $this->exceptionResponse($e);
    }
}
```

Only the fallback `GeneralErrorException` path is reported — `ModelNotFoundException`, `RouteNotFoundException`, `ValidationException`, and any custom `ExceptionContract` exception are expected/known conditions and aren't logged.

One dedicated builder method per envelope exception is also available — construct and render directly without `throw`/`catch`:

MethodBuilds`generalErrorExceptionResponse($request, ?$message, $statusCode = 500, ?$previous)``GeneralErrorException``modelNotFoundExceptionResponse($request, ?$message, $statusCode = 404)``ModelNotFoundException``routeNotFoundExceptionResponse($request, ?$message, $statusCode = 404)``RouteNotFoundException``validationExceptionResponse($request, $errors, ?$message, $statusCode = 422)``ValidationException````
public function show(Request $request, string $id)
{
    $user = User::find($id);

    if (! $user) {
        return $this->modelNotFoundExceptionResponse($request);
    }

    return $this->successResponse(UserResource::make($user));
}
```

### Debug traces: `withDebugTrace()`

[](#debug-traces-withdebugtrace)

`HasApiResponse::withDebugTrace(JsonResponse $response, Throwable $source): JsonResponse` — protected helper, appends a `debug` block (`exception`, `file`, `line`, `trace`) to an already-built envelope response. Frame `args` are stripped from the trace (may carry sensitive values like passwords/tokens). Used internally by the 4 envelope exceptions (`ValidationException`, `ModelNotFoundException`, `RouteNotFoundException`, `GeneralErrorException`) when rendering with a `$previous` exception and `app.debug` is `true` — see [Debug mode: raw message + trace](#debug-mode-raw-message--trace) below. Can also be called directly if you build custom exception rendering.

`ApiRequest`
------------

[](#apirequest)

`MMAE\ApiResponse\Request\ApiRequest` — `FormRequest` base class. Overrides `failedValidation()` to return `failedResponse()` (422) instead of Laravel's default redirect.

```
use MMAE\ApiResponse\Request\ApiRequest;

class StoreUserRequest extends ApiRequest
{
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        return [
            'email' => ['required', 'email'],
        ];
    }
}
```

Override defaults per-request by declaring properties:

```
class StoreUserRequest extends ApiRequest
{
    protected ?string $message = 'Please fix the errors below';
    protected ?int $statusCode = 422;
    // ...
}
```

Config defaults
---------------

[](#config-defaults)

`MMAE\ApiResponse\Configurations\Response` — static properties, override directly if needed:

- `$VALIDATION_FAILED_STATUS = 422`
- `$FAILED_STATUS = 400`
- `$VALIDATION_FAILED_MESSAGE = null` — `null` uses the translated `apiresponse::messages.validation_failed` line; set a string to override.

Static props, not config-file-backed. Set them once app boots (e.g. `AppServiceProvider::boot()`) to change defaults app-wide:

```
use MMAE\ApiResponse\Configurations\Response;

public function boot(): void
{
    Response::$FAILED_STATUS = 422;
    Response::$VALIDATION_FAILED_MESSAGE = 'The given data was invalid.';
}
```

Affects `failedResponse()` / `failedMessageResponse()` (via `$FAILED_STATUS`) and `ApiRequest::failedValidation()` (via `$VALIDATION_FAILED_STATUS` / `$VALIDATION_FAILED_MESSAGE`) whenever caller doesn't pass explicit `$statusCode`/`$message`.

Exceptions
----------

[](#exceptions)

`MMAE\ApiResponse\Exceptions\*` — throwable exceptions that render themselves as the standard envelope. Each implements `MMAE\ApiResponse\Contracts\ExceptionContract` (`render(Request): JsonResponse`), so throwing one anywhere in the app produces the envelope automatically — no extra wiring required. See [Rendering exceptions](#rendering-exceptions-exceptionresponse-and-per-exception-builders) above for the `HasApiResponse` helpers that build/render these directly.

ExceptionSignatureDefault statusDefault message key`ValidationException``(array|Collection $errors, ?string $message = null, int $statusCode = 422, ?Throwable $previous = null)`422`apiresponse::messages.validation_failed``ModelNotFoundException``(?string $message = null, int $statusCode = 404, ?Throwable $previous = null)`404`apiresponse::messages.resource_not_found``RouteNotFoundException``(?string $message = null, int $statusCode = 404, ?Throwable $previous = null)`404`apiresponse::messages.route_not_found``GeneralErrorException``(?string $message = null, int $statusCode = 500, ?Throwable $previous = null)`500`apiresponse::messages.something_went_wrong`Pass `null` (or omit) `$message` to use the translated default; pass a string to override it for that instance — an explicit message always wins, regardless of `app.debug`. Messages are resolved at `render()` time, using whichever locale is active when the response is built — not the locale at throw time.

### Mapping Laravel's own exceptions

[](#mapping-laravels-own-exceptions)

`Response::handleExceptions(Exceptions $exceptions)` maps Laravel's built-in exceptions to the matching envelope exception, for JSON requests only (non-JSON requests fall through to Laravel's default handling). Wire it in `bootstrap/app.php`:

```
use MMAE\ApiResponse\Configurations\Response;

->withExceptions(function (Exceptions $exceptions) {
    Response::handleExceptions($exceptions);
})
```

Handles: `Illuminate\Validation\ValidationException`, `Illuminate\Database\Eloquent\ModelNotFoundException`, unmatched routes (`NotFoundHttpException`), and any other `Throwable` as a `GeneralErrorException`.

### Debug mode: raw message + trace

[](#debug-mode-raw-message--trace)

When an envelope exception is auto-constructed from a real caught exception (i.e. via `Response::handleExceptions`, which always passes the original as `$previous`), `render()` behaves differently based on `config('app.debug')`:

- **`app.debug = true`** — `message` is the original exception's raw `getMessage()`, and a `debug` block is added to the envelope: `{ "exception": "...", "file": "...", "line": ..., "trace": [...] }`. Frame `args` are stripped from every trace entry (they can carry sensitive values like passwords or tokens).
- **`app.debug = false`** — `message` is the translated default (or your override), and no `debug` key is present at all.

This only applies to exceptions carrying a `$previous` (i.e. mapped by `handleExceptions`). If you throw one of these exceptions directly in app code with an explicit `$message`, that message is shown as-is regardless of `app.debug` — it's an intentional, developer-authored message, not something to hide.

Unrecognized throwables passed to `exceptionResponse()` are also reported to the app's exception handler via `report()` before being wrapped — see [Rendering exceptions](#rendering-exceptions-exceptionresponse-and-per-exception-builders) above.

Translations
------------

[](#translations)

Default messages are translated via `apiresponse::messages.*` (English + Arabic shipped). Laravel resolves the active locale automatically; override a locale's strings by publishing:

```
php artisan vendor:publish --tag=apiresponse-lang
```

This copies the lang files to `lang/vendor/apiresponse/{locale}/messages.php` in the host app, where they take priority over the package's own.

Artisan command
---------------

[](#artisan-command)

```
php artisan make:request-api {name}
```

Generates a request class extending `ApiRequest` into `App\Http\Requests\Api`, using `src/stubs/request.stub`.

Testing &amp; tooling
---------------------

[](#testing--tooling)

Package tests live in `src/tests` (Testbench, not top-level `tests/`), written in Pest. `src/tests/Pest.php` binds `TestCase` to `Unit`/`Feature`.

```
composer test        # vendor/bin/pest --test-directory=src/tests
composer analyse     # vendor/bin/phpstan analyse (level: max, via larastan)
composer format      # vendor/bin/pint
composer refactor    # vendor/bin/rector process (src/, PHP 8.4 + Laravel 13 rule sets)
```

`phpstan.neon.dist` and `rector.php` both scope to `src/` (skip `src/stubs` and `src/tests`).

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance70

Regular maintenance activity

Popularity18

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity43

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~352 days

Total

3

Last Release

47d ago

Major Versions

1.x-dev → v2.0.02026-07-02

### Community

Maintainers

![](https://www.gravatar.com/avatar/4bbc9de6ae871f11b4eb2f286d1172b00bab5fb48cdd5eeda80a79a9740b7006?d=identicon)[Mahmoud1478](/maintainers/Mahmoud1478)

---

Top Contributors

[![Mahmoud1478](https://avatars.githubusercontent.com/u/69082913?v=4)](https://github.com/Mahmoud1478 "Mahmoud1478 (7 commits)")

###  Code Quality

TestsPest

Static AnalysisPHPStan, Rector

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/mmae-apiresponse/health.svg)

```
[![Health](https://phpackages.com/badges/mmae-apiresponse/health.svg)](https://phpackages.com/packages/mmae-apiresponse)
```

###  Alternatives

[exsyst/swagger

A php library to manipulate Swagger specifications

35816.5M7](/packages/exsyst-swagger)[lucasdotvin/laravel-soulbscription

A straightforward interface to handle subscriptions and features consumption.

709209.3k](/packages/lucasdotvin-laravel-soulbscription)[pimax/fb-messenger-php

Facebook Messenger Bot PHP API

313188.5k2](/packages/pimax-fb-messenger-php)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
