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 Client Laravel Package

macsidigital/laravel-api-client

A Laravel package that provides a clean, configurable API client for consuming external and internal HTTP APIs. It offers a fluent interface, centralized endpoint configuration, and streamlined request handling to simplify integrations in Laravel applications.

Deep Wiki
Context7

Getting Started

  • Install with composer require macsidigital/laravel-api-client. The package ships a Laravel service provider that should be auto-discovered; if not, register Macsidigital\ApiClient\ApiClientServiceProvider in config/app.php.
  • Publish any package config before writing code: php artisan vendor:publish --provider="Macsidigital\ApiClient\ApiClientServiceProvider". Set the base URI, timeout, and default headers from .env rather than hard-coding them.
  • Look at vendor/macsidigital/laravel-api-client/src/ first. The base ApiClient class and the request/token traits are the real documentation for this package — the README is thin relative to the source.
  • First use case: wrap one third-party API in a dedicated client class, bind it in the container, and inject it into a service/job. Avoid calling the package directly from controllers.
namespace App\Services;

use Macsidigital\ApiClient\ApiClient;

class AcmeClient extends ApiClient
{
    protected $baseUri = 'https://api.acme.test/v1';

    public function users(): array
    {
        return $this->get('users')->json();
    }
}

Bind it once so auth and base URI are configured in one place:

$this->app->singleton(AcmeClient::class, function () {
    $client = new AcmeClient();
    $client->withToken(config('services.acme.token'));
    return $client;
});

Implementation Patterns

  • One client per external service. Subclass the base client (or use the package’s request trait) and put service-specific methods on it: users(), createOrder(), refund(). Keep HTTP details out of controllers and jobs.
  • Configure in the constructor. Base URI, auth token, Accept/Content-Type, and timeout belong in the client, not at every call site.
  • Use the verb methods plus chaining. Typical shape is $this->withHeaders([...])->post('orders', $payload). Treat modifiers as per-request state and avoid relying on them leaking into later calls.
  • Normalize responses at the boundary. Convert json()/object()/collect() output into DTOs or arrays before returning to domain code. Controllers should never see a raw Guzzle response.
  • Centralize error translation. Check successful() or call throw(), then convert failures into domain exceptions (AcmeApiException) with status code and response body attached.
  • Token handling. Store per-user or per-tenant tokens in the database, set them on a freshly resolved client, and handle 401 by refreshing once and retrying the original request.
  • Retries. Use retry/timeout helpers for idempotent GETs. Do not blindly retry POSTs unless the upstream API supports idempotency keys.
  • Testing. Fake the HTTP layer in tests — never hit the real API in CI. If the package delegates to Laravel’s Http facade, Http::fake() works; if it talks to Guzzle directly, inject a Guzzle client with a MockHandler, or bind a fake subclass of your client.
  • Pagination. Implement a generator on your client that loops pages and yields items, so callers can use foreach without thinking about page numbers.

Gotchas and Tips

  • Statefulness. Many small API-client packages keep the last request/response on the instance. A singleton client reused across users can leak auth headers or response state. Resolve a fresh client per auth context, or reset explicitly.
  • Base URI joining. Watch trailing-slash behavior: https://api.test/v1 + /users and https://api.test/v1/ + users may not produce the same URL. Pick one convention in your client and stick to it.
  • JSON vs form encoding. Defaults vary. Be explicit with asJson() / asForm() when the upstream API is picky.
  • Silent 4xx/5xx. Most clients do not throw on non-2xx by default. If you don’t call throw() or check successful(), a failed request looks like an empty successful one.
  • Http::fake() may not intercept. Confirm whether the package wraps Laravel’s HTTP client or Guzzle directly before writing tests; this is the most common source of “my fake isn’t working” confusion.
  • Timeouts. Defaults are often generous or absent. Set connect and total timeouts explicitly, especially for queue workers.
  • Config caching. After changing .env values used by the package config, run php artisan config:clear (or rebuild config:cache).
  • Log redaction. Authorization headers and tokens end up in logs easily. Add a redaction step or avoid logging full requests in production.
  • Low adoption risk. With ~20 stars, expect sparse docs and occasional unmaintained edges. Pin the version in composer.json, read the source before upgrading, and be prepared to fork or wrap the client behind your own interface so you can swap it out.
  • Debugging. Dump the prepared request/response (getRequest()/getResponse() if exposed by the traits) or attach a Guzzle logging middleware. This is faster than guessing at URL encoding or header issues.
  • Extension points. Prefer subclassing your own AcmeClient and publishing config over editing vendor files. If the package supports middleware/handlers, add logging, correlation IDs, and retry logic there rather than duplicating it in every method.
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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums