Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Api Helper Laravel Package

arcanedev/laravel-api-helper

ArcaneDev's Laravel API Helper provides lightweight utilities for JSON API development, including standardized response helpers for success and error payloads, helping keep controllers concise and API output consistent across your Laravel application.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package and publish its config:

composer require arcanedev/laravel-api-helper
php artisan vendor:publish --provider="Arcanedev\ApiHelper\ApiHelperServiceProvider" --tag=config

On Laravel 5.5+ auto-discovery registers the provider. On older Laravel (or if discovery fails — see Gotchas) add the provider and facade alias to config/app.php:

'providers' => [
    Arcanedev\ApiHelper\ApiHelperServiceProvider::class,
],
'aliases' => [
    'ApiResponse' => Arcanedev\ApiHelper\Facades\Response::class, // verify class name in src/Facades/
],

Where to look first: the published config file (config/api-helper.php). It governs the response envelope — the keys used for success/error/message/data, the default status code, content type, and JSON encode options. Read it before wiring anything up; almost every "why does my JSON look like that" question is answered there.

First use case — a controller that returns JSON in the package's shape:

use Arcanedev\ApiHelper\Facades\Response as ApiResponse; // alias avoids the Illuminate collision

public function show(User $user)
{
    return ApiResponse::success($user->toArray());
}

public function store(StoreUserRequest $request)
{
    $user = User::create($request->validated());

    return ApiResponse::success($user->toArray(), 201);
}

Smoke-test with php artisan serve and curl -i http://localhost:8000/api/users/1 — the -i matters, because you want to confirm the Content-Type header the package sets, not just the body. If the package registers an api_response() helper in your version, it's a lighter-weight alias for the same class; check src/helpers.php in the vendor directory.

Implementation Patterns

1. Consistent envelope across a controller. The whole point of the package is that every endpoint returns the same shape. Lean on the facade instead of response()->json() so success/error payloads stay in sync:

return ApiResponse::success($order->toArray());
return ApiResponse::error('Order is already shipped.', 409);
return ApiResponse::notFound('Order not found.');

2. Centralize error formatting in the exception handler. This is where the package pays for itself — one place renders every error consistently:

// app/Exceptions/Handler.php
public function render($request, Throwable $e)
{
    if ($request->expectsJson() || $request->is('api/*')) {
        if ($e instanceof ModelNotFoundException)      return ApiResponse::notFound();
        if ($e instanceof AuthenticationException)      return ApiResponse::error('Unauthenticated', 401);
        if ($e instanceof AuthorizationException)       return ApiResponse::error('Forbidden', 403);
        if ($e instanceof ValidationException)          return ApiResponse::error($e->errors(), 422);
        if ($e instanceof HttpExceptionInterface)       return ApiResponse::error($e->getMessage(), $e->getStatusCode());
    }

    return parent::render($request, $e);
}

3. Override FormRequest failure output. By default failedValidation() throws a redirect/JSON response that bypasses your envelope. Force it through the helper:

protected function failedValidation(Validator $validator)
{
    throw new HttpResponseException(
        ApiResponse::error($validator->errors()->toArray(), 422)
    );
}

4. Wrap it in a base controller trait. You don't want use Arcanedev\...\Facades\Response as ApiResponse; in fifty controllers, and you want a single seam to swap in if you ever drop the package:

trait ApiResponses
{
    protected function ok($data = null, int $status = 200)   { return ApiResponse::success($data, $status); }
    protected function fail($message, int $status = 400)    { return ApiResponse::error($message, $status); }
    protected function created($data = null)                { return $this->ok($data, 201); }
}

5. Pagination. Laravel's LengthAwarePaginator::toArray() already exposes data, current_page, total, etc. Passing it through success() is the safe path if the package doesn't have a dedicated paginator helper:

return ApiResponse::success(User::paginate(25)->toArray());

6. Feature-test the envelope, not just the status. Because the package owns the JSON shape, assert on it:

$this->getJson("/api/users/{$user->id}")
    ->assertOk()
    ->assertJsonStructure(['success', 'status_code', 'data' => ['id', 'email']]);

This gives you a contract test that will fail loudly if a package upgrade (or your migration off it) changes the shape.

Gotchas and Tips

  • Maintenance risk is the headline. Last release 2019-02-28, 5 stars, 0 dependents. Its composer.json almost certainly pins laravel/framework to 5.*/6.* — installing on Laravel 8+ will require either a --with-all-dependencies fight or a fork. Treat this as a ~50-line utility you adopt, not infrastructure you inherit.

  • Facade name collides with Illuminate\Support\Facades\Response. If you write use Arcanedev\ApiHelper\Facades\Response; in a file that also touches Laravel's Response, you'll get confusing behavior. Always alias (as ApiResponse).

  • Auto-discovery silently skips on some versions. If the facade throws Class not found or A facade root has not been set, drop the provider into config/app.php manually and run php artisan config:clear.

  • Config cache. Editing config/api-helper.php has no effect until php artisan config:clear (or config:cache in prod). This trips people up in Docker builds where the config is cached at image build time and the file is edited afterward.

  • Status codes are not inferred. success($data) typically defaults to 200; 201 and 204 must be passed explicitly. Check the config's default — a package default of 200 on a DELETE endpoint is a subtle API bug.

  • Debug leakage. In APP_DEBUG=true, ensure your Handler::render branch doesn't pass $e->getMessage() for 500s unless you want stack traces in responses. Only surface getMessage() for 4xx HttpExceptions.

  • Content-Type and charset. Some versions default to application/json;charset=utf-8 (no space). Clients that do strict string matching on Content-Type will care. Verify with curl -i once and then forget it.

  • CORS is out of scope. This package formats bodies only; it does nothing for preflight. Use fruitcake/laravel-cors or Laravel 7+'s built-in CORS config — don't expect the helper to help here.

  • Extension points. If you need extra methods (accepted(), conflict(), tooManyRequests()), add macros on the facade's root class from a service provider, or subclass and rebind the singleton. Don't patch vendor files.

  • The exit ramp. Given the age and adoption, plan for a 20-line replacement when you outgrow it:

    // App\Support\ApiResponse
    public static function success($data = null, int $status = 200) {
        return response()->json(['success' => true, 'status_code' => $status, 'data' => $data], $status);
    }
    public static function error($message, int $status = 400) {
        return response()->json(['success' => false, 'status_code' => $status, 'message' => $message], $status);
    }
    

    The base-controller trait pattern in Implementation Patterns means that swap is a one-file change plus a use statement — build it that way from day one.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core