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

Api Bundle Laravel Package

pdfloresjdav/api-bundle

A Laravel/PHP bundle that streamlines building REST APIs, with organized routing, controllers, request validation, and consistent JSON responses out of the box. A practical starting point for teams wanting a structured, reusable API layer without boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

Step 0 — verify it actually boots in Laravel before writing any code against it. The description claims a Laravel-native service provider, but the DYB naming and *Bundle suffix are Symfony conventions. One minute of verification saves a day of pain:

composer require pdfloresjdav/api-bundle
php artisan package:discover   # does a service provider register?
cat vendor/pdfloresjdav/api-bundle/composer.json | grep -E '"type"|symfony|illuminate'

If type is symfony-bundle or the requires are symfony/*, stop and treat the source as reference code — port the DTOs and response logic into your own app/Support/Api/ namespace instead of depending on it.

Where to look first (in this order):

  • composer.json — PHP/Laravel version constraints; this is the first thing that breaks on current majors.
  • src/*ServiceProvider.php — what gets registered globally (routes, middleware, exception handlers).
  • config/*.php (or the publish tag) — the real configuration surface; this is what you will live in.
  • Route registration file — versioned prefix, middleware group, controller namespace assumptions.
  • Transformer/resource classes — how Eloquent models map to JSON.
  • Response/error-envelope classes — how success and failure payloads are shaped.

First use case — scaffold one versioned read endpoint and one write endpoint against a throwaway model. That exercises routing, serialization, success envelope, validation error envelope, and exception handling in a single afternoon. If all five work, you have a bounded baseline and can decide. If any of them require reading internals to understand, that is your signal to fork rather than depend.

php artisan vendor:publish --provider="Pdfloresjdav\ApiBundle\...ServiceProvider"
php artisan route:list --path=api
curl -i http://localhost/api/v1/ping

Implementation Patterns

Pattern A — Convention-first CRUD (the intended happy path)

The package's value is standardized response shape and transformers. Lean into it: keep controllers thin, put serialization in the package's transformer layer, and let the envelope be the contract your frontend codes against.

// routes/api.php — rely on the package's versioned group if it registers one
Route::prefix('v1')->middleware('api')->group(function () {
    Route::apiResource('orders', OrderController::class);
});

// app/Http/Controllers/Api/OrderController.php
public function show(Order $order)
{
    return $this->respond(OrderTransformer::make($order)); // package envelope
}

The win is consistency across endpoints. The trap is re-implementing Laravel's JsonResource alongside it — pick one serialization path and stick to it.

Pattern B — Wrap the package behind your own base controller

Do not let package response helpers leak into domain code. Introduce a thin base controller (or trait) that delegates:

abstract class ApiController
{
    protected function ok($data, int $status = 200) { /* delegates to package */ }
    protected function fail(string $code, string $message, int $status) { /* delegates */ }
}

When the package is abandoned — and with 0 stars/0 dependents that is the default expectation — you swap one file, not every controller.

Pattern C — Validation errors through FormRequests, not the package

The package's error envelope should consume Laravel's validation exception, not replace it. Keep standard FormRequest validation and confirm the package's exception handler formats the 422 payload into its envelope. If it registers a global exception handler via the service provider, verify it does not clobber your own App\Exceptions\Handler customizations — check bootstrap/app.php / Handler::render after install.

Pattern D — Transformers as plain PHP, not as a framework hook

Transformer classes are usually just PHP that maps an Eloquent model to an array. Even in "adopt" mode, prefer composing them with ->load() and ->loadCount() eager loads yourself so you control N+1:

$order = Order::with('customer', 'items.product')->withCount('items')->findOrFail($id);
return $this->ok(OrderTransformer::make($order));

Treat the package transformer as a formatting function, not an ORM abstraction. That keeps it portable if you later fork.

Pattern E — Versioned routing as a boundary, not a checkbox

If the package provides a versioned prefix, use it as the actual extension point: new versions get new transformer classes and new route files, but the same base ApiController. Do not branch inside transformers on version — it compounds quickly.

Pattern F — Contract test the envelope

Write one feature test per endpoint that asserts the JSON envelope shape (data, meta, errors, status codes). Because the envelope is supplied by an unmaintained package, that test is your upgrade tripwire when you eventually swap it out.

Gotchas and Tips

  • Do not assume it is Laravel. The *Bundle naming and DYB description are red flags; verify the service provider boots before architecting around it.
  • Zero dependents means zero compatibility signal. A Laravel major bump will almost certainly be your problem, not upstream's. Pin laravel/framework in composer.json and pin the package to an exact version ("1.2.3", not "^1.2").
  • Global side effects on install. Service providers that register routes, middleware, or exception handlers can silently conflict with your own api.php, App\Exceptions\Handler, or bootstrap/app.php. Run php artisan route:list and diff it before and after install.
  • Config publish is a one-way door. Once published, config/api.php is yours; upstream config changes will not propagate. That is fine, but note it — you are now maintaining it.
  • Config cache. If you add or edit the package's config, php artisan config:clear (dev) and php artisan config:cache (prod) — a stale cache is the most common "why is my prefix still v0" bug.
  • Response envelope vs. Laravel conventions. The envelope will not match JsonResource or ValidationException defaults. Decide early whether the package's envelope is authoritative; if it is, disable or adapt App\Exceptions\Handler custom formatting to avoid double-wrapping errors.
  • Transformer duplication. Do not use the package's transformer and JsonResource on the same model. Mixed serialization is the fastest way to inconsistent payloads.
  • Debugging serialization. dd($transformer->toArray($model)) is more reliable than reading the source; if the output is surprising, check whether $hidden, $visible, $appends, and $with on the model are being respected or bypassed.
  • Eager loading is still your job. Most transformer layers do not prevent N+1. Enable DB::listen in a local run and assert query counts in tests.
  • Versioned prefix conflicts. If the package registers its own /api/v1 group, do not also define Route::prefix('v1') in api.php — you will double-prefix (/api/v1/v1/...) or shadow routes. Pick one owner.
  • Extension points worth using: the published config file, the transformer base class, and the base controller/response helper. Extension points worth avoiding: subclassing the service provider or patching vendor files — both vanish on reinstall.
  • When to stop. If you have read the service provider and the transformer layer and still cannot predict what a request returns without running it, that is the fork-or-write-it-yourself signal. For a package with no upstream maintenance, the bar for "understand it fully" is higher, not lower.
  • Fork checklist (if you go that way): keep the license header, strip DependencyInjection/ and Symfony wiring if present, add mergeConfigFrom + publishes, re-namespace to App\Support\Api\, and require via a vcs repository entry. Budget a day; ship a ApiEnvelope contract test in the same PR.
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.
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
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