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.
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.php artisan vendor:publish --provider="Macsidigital\ApiClient\ApiClientServiceProvider". Set the base URI, timeout, and default headers from .env rather than hard-coding them.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.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;
});
users(), createOrder(), refund(). Keep HTTP details out of controllers and jobs.Accept/Content-Type, and timeout belong in the client, not at every call site.$this->withHeaders([...])->post('orders', $payload). Treat modifiers as per-request state and avoid relying on them leaking into later calls.json()/object()/collect() output into DTOs or arrays before returning to domain code. Controllers should never see a raw Guzzle response.successful() or call throw(), then convert failures into domain exceptions (AcmeApiException) with status code and response body attached.401 by refreshing once and retrying the original request.GETs. Do not blindly retry POSTs unless the upstream API supports idempotency keys.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.foreach without thinking about page numbers.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.asJson() / asForm() when the upstream API is picky.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..env values used by the package config, run php artisan config:clear (or rebuild config:cache).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.getRequest()/getResponse() if exposed by the traits) or attach a Guzzle logging middleware. This is faster than guessing at URL encoding or header issues.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.How can I help you explore Laravel packages today?