Installation:
composer require chaplean/rest-client-bundle
Ensure EightPointsGuzzleBundle is registered in AppKernel.php (dependency).
Basic Configuration:
Define a client in config.yml:
eight_points_guzzle:
clients:
my_api:
base_url: 'https://api.example.com'
timeout: 30
First Use Case: Inject the client service and make a request:
use Chaplean\Bundle\RestClientBundle\Client\ClientInterface;
class MyService
{
public function __construct(ClientInterface $client)
{
$this->client = $client;
}
public function fetchData()
{
return $this->client->get('my_api', '/endpoint');
}
}
Chaplean\Bundle\RestClientBundle\Client\ClientInterface defines the core methods (get, post, put, delete, etc.).Service Integration: Bind the client to a service and reuse it for API interactions:
// src/MyBundle/Service/MyApiService.php
class MyApiService
{
public function __construct(private ClientInterface $client) {}
public function createResource(array $data): array
{
return $this->client->post('my_api', '/resources', [
'json' => $data,
]);
}
}
Request Customization: Use Guzzle options directly:
$this->client->get('my_api', '/endpoint', [
'query' => ['filter' => 'active'],
'headers' => ['Authorization' => 'Bearer token'],
]);
Response Handling:
Parse responses with Symfony’s JsonResponse or custom logic:
$response = $this->client->get('my_api', '/users');
$users = json_decode($response->getBody(), true);
API Abstraction Layer: Create a dedicated service per API to encapsulate endpoints and logic:
// src/MyBundle/Service/StripeService.php
class StripeService
{
public function __construct(private ClientInterface $client) {}
public function chargeCustomer(string $customerId, float $amount): array
{
return $this->client->post('stripe_api', '/charges', [
'json' => ['amount' => $amount, 'customer' => $customerId],
]);
}
}
Error Handling: Use Guzzle’s exception handling or wrap calls in try-catch:
try {
$this->client->get('my_api', '/sensitive-data');
} catch (\GuzzleHttp\Exception\RequestException $e) {
// Log or rethrow with custom message
throw new \RuntimeException('API request failed', 0, $e);
}
Configuration Management:
Dynamically switch environments (e.g., dev vs. prod) via parameters.yml:
# config_dev.yml
eight_points_guzzle:
clients:
my_api:
base_url: 'https://dev-api.example.com'
Dependency Injection:
Prefer constructor injection for testability. Use @autowire in services:
services:
App\Service\MyApiService:
arguments:
$client: '@chaplean_rest_client.client'
Middleware:
Leverage Guzzle middleware (e.g., retry, logging) via EightPointsGuzzleBundle:
eight_points_guzzle:
clients:
my_api:
middleware:
- EightPoints\GuzzleBundle\Middleware\RetryMiddleware
Testing:
Mock the ClientInterface in PHPUnit:
$mockClient = $this->createMock(ClientInterface::class);
$mockClient->method('get')->willReturn(new \GuzzleHttp\Psr7\Response(200, [], '{}'));
$service = new MyApiService($mockClient);
Missing Dependencies:
EightPointsGuzzleBundle will cause ClientInterface to fail.AppKernel.php before ChapleanRestClientBundle.Logging Overhead:
config.yml if unused:
eight_points_guzzle:
logging: false
Base URL Mismatches:
base_url in config.yml leads to 404s or redirects.curl or Postman before debugging.Response Parsing:
getBody() directly if needed:
$body = $this->client->get('my_api', '/plaintext')->getBody();
Enable Guzzle Debugging: Add a middleware to log requests/responses:
eight_points_guzzle:
clients:
my_api:
middleware:
- EightPoints\GuzzleBundle\Middleware\DebugMiddleware
Check Headers:
Missing or malformed headers (e.g., Content-Type: application/json) cause parsing errors.
var_dump($response->getHeaders());
Timeouts: Default timeouts may be too short for slow APIs.
config.yml:
eight_points_guzzle:
clients:
my_api:
timeout: 60
Reuse Clients:
Define multiple clients in config.yml for different APIs:
eight_points_guzzle:
clients:
stripe: { base_url: 'https://api.stripe.com' }
paypal: { base_url: 'https://api.paypal.com' }
Environment-Specific Configs:
Use %kernel.environment% to switch configs:
# config_%env%.yml
eight_points_guzzle:
clients:
my_api:
base_url: '%api_base_url%'
Extend Functionality:
Create custom clients by implementing ClientInterface:
class CustomClient implements ClientInterface
{
public function get(string $clientName, string $endpoint, array $options = []): ResponseInterface
{
// Add pre-processing logic (e.g., auth tokens)
return $this->guzzleClient->get($endpoint, $options);
}
}
Rate Limiting:
Use Guzzle’s delay option to avoid hitting API limits:
$this->client->get('my_api', '/rate-limited', [
'delay' => 1000, // 1-second delay
]);
Security:
config.yml. Use Symfony’s parameter_bag:
parameters:
api_token: '%env(API_TOKEN)%'
How can I help you explore Laravel packages today?