aurelien/create-client-bundle
Installation
composer require aurelien/create-client-bundle
vendor/composer/autoload_psr4.php for the namespace Aurelien\CreateClientBundle.Basic Usage
config/app.php under providers:
Aurelien\CreateClientBundle\CreateClientBundleServiceProvider::class,
php artisan vendor:publish --provider="Aurelien\CreateClientBundle\CreateClientBundleServiceProvider" --tag="config"
config/create-client-bundle.php for default settings (if published).First Use Case: Generating a Client Class
php artisan create:client --name=MyApiClient --base-url=https://api.example.com
app/Clients/MyApiClient.php with basic HTTP methods (e.g., get(), post()).Client Generation
--name and --base-url flags to generate clients for different APIs:
php artisan create:client --name=StripeClient --base-url=https://api.stripe.com
getHeaders() method:
class StripeClient extends BaseClient {
protected function getHeaders(): array {
return array_merge(parent::getHeaders(), [
'Authorization' => 'Bearer ' . config('services.stripe.key'),
]);
}
}
Integration with Laravel Services
$this->app->singleton(MyApiClient::class, function ($app) {
return new MyApiClient(config('services.my_api.url'));
});
public function __construct(private MyApiClient $client) {}
API Request Handling
public function fetchData() {
$response = $this->client->get('/endpoint');
return response()->json($response->data);
}
Http facade or custom logic:
$data = json_decode($response->body, true);
Testing
$this->mock(MyApiClient::class, function ($mock) {
$mock->shouldReceive('get')->andReturn((object) ['data' => []]);
});
.env and bind them to config:
MY_API_URL=https://api.example.com
'url' => env('MY_API_URL'),
class MyApiClient extends BaseClient {
protected function handleResponse($response) {
if ($response->status !== 200) {
throw new ApiException($response->body);
}
return json_decode($response->body, true);
}
}
protected function logRequest($method, $url, $data) {
\Log::info("API Call: {$method} {$url}", ['data' => $data]);
}
Namespace Conflicts
app/Clients/) doesn’t clash with existing classes. Customize the output path in the artisan command if needed (check the package’s source for extension points).Missing Dependencies
guzzlehttp/guzzle). Add it manually if HTTP requests fail:
composer require guzzlehttp/guzzle
Config Publishing
register() method to customize behavior:
$this->app->singleton('client', function () {
return new MyApiClient(config('custom.api_url'));
});
Artisan Command Issues
app/Console/Kernel.php.app/Clients/ for the generated client class. If empty, the artisan command may not be working.APP_DEBUG=true in .env to see detailed errors.$client = new MyApiClient();
$client->getClient()->getEmitter()->attach(
new \GuzzleHttp\Middleware::tap(function ($request) {
\Log::debug('Request:', [
'url' => (string) $request->getUri(),
'method' => $request->getMethod(),
]);
})
);
Extend Base Client
protected function getClient() {
return new \GuzzleHttp\Client([
'timeout' => 30,
'headers' => $this->getHeaders(),
]);
}
Use Traits for Reusability
trait ApiClientTrait {
protected function paginate($url, $perPage = 20) {
$response = $this->get("{$url}?per_page={$perPage}");
return $response->data;
}
}
Document Clients
/**
* Fetches user data from the API.
*
* @param int $id User ID
* @return array User data
*/
public function getUser($id) { ... }
Leverage Laravel Mixins
mixin feature to add methods to the client dynamically:
\Illuminate\Support\Facades\Blade::mixin(function () {
// Add custom Blade directives for API responses
});
How can I help you explore Laravel packages today?