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

Basic Api Bundle Laravel Package

imiskuf/basic-api-bundle

imiskuf/basic-api-bundle is a lightweight PHP package for quickly scaffolding basic API endpoints. It provides a simple structure and reusable components to help expose JSON data with minimal configuration and boilerplate, making it suitable for small services and prototypes.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check before you type composer require: this is a Symfony bundle, not a Laravel package. It has type: symfony-bundle semantics, DI extension classes under DependencyInjection/, and Resources/config/services.yaml. There is no Illuminate\Support\ServiceProvider, no extra.laravel block, and no config/*.php to publish. If you're in a Laravel codebase, "installing" it is the wrong framing — you're reading source to port it, not adopting a dependency.

Minimal path, in order:

  1. Read composer.json on GitHub first. Check autoload.psr-4 for the root namespace, the require block for the Symfony/PHP floor (a bundle from the Symfony 3.4/4.x era will pin symfony/* versions that clash with anything modern), and whether it's type: symfony-bundle. If the constraint is ^3.4 || ^4.0, stop — it will not resolve against a current Laravel app.
  2. Attempt composer require imiskuf/basic-api-bundle in a throwaway Laravel project, not your real one. Expected outcome: a resolution conflict. That failure is the fastest confirmation that you should vendor rather than install.
  3. Open src/ — specifically any DependencyInjection/Configuration.php (the config tree: base URI, auth, timeouts) and whatever sits in src/Service/ or src/Client/. That client class is the entire package's value. The rest is Symfony plumbing you'll discard.
  4. Skip bundle registration entirely. There's no config/bundles.php in Laravel and no reason to fake one.

First use case to port: a base-URI + credentials HTTP client you inject into a single service class, called from a controller or a queued job — one third-party API, low-consequence surface. That's the whole pattern the package encodes.

Implementation Patterns

If you are genuinely on Symfony (rare given your stack): register in config/bundles.php, configure under config/packages/basic_api.yaml using the keys exposed by Configuration.php, inject credentials via %env(API_BASE_URI)% / %env(API_TOKEN)%, and constructor-inject the client into an adapter service — never call it straight from a controller.

If you are on Laravel — the realistic path — port, don't install:

  • Copy the client class into app/Services/VendorName/ApiClient.php. Delete the DependencyInjection, Resources/config, and any Extension classes; they are Symfony-only.
  • If it was built on Guzzle directly, rewrite the transport layer to use Illuminate\Support\Facades\Http. You keep the package's shape (method-per-endpoint, DTOs, endpoint constants) and drop the transport, which is the part Laravel already gives you.
  • Bind it as a singleton in a ServiceProvider:
    $this->app->singleton(ApiClient::class, fn () =>
        new ApiClient(
            baseUri: config('services.vendor.base_uri'),
            token:   config('services.vendor.token'),
        )
    );
    
  • Add a services.php entry ('vendor' => ['base_uri' => env('VENDOR_API_URI'), 'token' => env('VENDOR_API_TOKEN')]). Never let the ported class read $_ENV or getenv() directly — that's the habit Symfony bundles fall into and it bypasses Laravel's config cache.
  • Put the client behind an interface (VendorApiContract) and bind the interface, not the concrete class. Because the source is unmaintained, the whole point is that a swap costs one binding.
  • Wrap calls in a thin domain-facing adapter (app/Services/VendorName/OrdersGateway.php) that maps the raw payload into your own DTOs. Do not let the package's response array shape leak into controllers or models.
  • For anything queue-eligible, dispatch a job that resolves the client from the container — don't call the API inline in a request cycle.
  • Add Http::retry(3, 200, throw: false), explicit ->timeout(5) / ->connectTimeout(2), and a 429 handler. The bundle almost certainly ships none of this; you're adding it on port, not inheriting it.

Contract tests over unit tests. Point the ported client at a mocked Http::fake() for happy paths, and at a real upstream (staging or recorded fixtures) for the DTO mapping. The upstream contract is what drifts; the bundle itself has no test suite to lean on.

Gotchas and Tips

  • The install is the first trap. A 0-star, 0-dependent bundle is almost certainly Composer-incompatible with a current Laravel app. Try it in a scratch project before you try it in composer.json. If it resolves, audit its require tree with composer audit immediately — its HTTP and serialization transitives are unaudited.
  • No service provider, no facade, no config publish. Don't go looking for php artisan vendor:publish. There is nothing to publish. The config is a Symfony Configuration tree, which you reimplement as config/services.php.
  • Config cache kills getenv(). If you copy a class that reads environment variables directly, php artisan config:cache will freeze the value (or blank it) and you'll chase a "works in dev, broken in prod" bug. Always route through config().
  • Debugging a ported client: use Http::fake() for shape, and Http::dd() when you need to inspect an actual outbound request. Log the request ID and latency from within the adapter, not the client — the client should stay dumb.
  • Auth, retries, backoff, rate limits, and observability are not in the box. The package name is "basic" for a reason. If any of those matter for your surface, you're not porting this package — you're writing a client, and you should start from Laravel's Http client (or Saloon) and skip the bundle entirely. That's a legitimate, common outcome.
  • Extension point that matters: the constructor signature. When you vendor the class, pin it to an interface and inject config through the constructor. That single decision is the difference between a reversible spike and a 6-month anchor.
  • Treat the source as read-only reference. If you keep it, vendor into app/Services/… or a private VCS repo — never a Packagist dependency you can't patch. MIT makes this trivially legal.
  • Zero dependents means zero Stack Overflow answers. When it breaks, you own it, and the answer comes from reading the source you vendored. Write the runbook at merge time, not at incident time.
  • Kill criteria, stated up front: if the audit shows the client is <150 lines with no signing or pagination edge cases, stop porting and reimplement against Http directly. Saving a day of typing isn't worth owning an unfamiliar Symfony bundle forever.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource