age/api-bundle
Symfony2 bundle for simplifying connections to external APIs. Provides a straightforward way to configure and call remote services from your application, aiming to keep API integrations clean and easy to manage.
Install the Bundle
Add to composer.json:
composer require sinevar/age-api-bundle
Enable in config/bundles.php:
return [
// ...
Sinevar\AGEApiBundle\SinevarAGEApiBundle::class => ['all' => true],
];
Configure API Clients
Define API endpoints in config/packages/sinevar_age_api.yaml:
sinevar_age_api:
clients:
example_api:
base_uri: 'https://api.example.com/v1'
auth:
type: 'bearer'
token: '%env(API_TOKEN)%'
timeout: 30
First API Call Inject the client service and make a request:
use Sinevar\AGEApiBundle\Client\ApiClientInterface;
class MyService
{
public function __construct(private ApiClientInterface $apiClient) {}
public function fetchData()
{
$response = $this->apiClient->get('example_api', '/users');
return json_decode($response->getBody(), true);
}
}
src/Sinevar/AGEApiBundle/Resources/doc/ for usage examples.src/Sinevar/AGEApiBundle/Client/ApiClientInterface for available methods (get, post, put, delete).config/packages/sinevar_age_api.yaml for customization.Use dependency injection to centralize API logic:
// src/Service/UserService.php
class UserService
{
public function __construct(
private ApiClientInterface $apiClient,
private LoggerInterface $logger
) {}
public function createUser(array $data): array
{
try {
$response = $this->apiClient->post('example_api', '/users', $data);
$this->logger->info('User created', ['data' => $data]);
return json_decode($response->getBody(), true);
} catch (ClientException $e) {
$this->logger->error('API Error', ['error' => $e->getMessage()]);
throw new \RuntimeException('Failed to create user');
}
}
}
Wrap responses in a DTO or Value Object:
// src/ValueObject/UserResponse.php
class UserResponse
{
public function __construct(
public int $id,
public string $name,
public array $metadata
) {}
public static function fromApiResponse(array $data): self
{
return new self(
id: $data['id'],
name: $data['name'],
metadata: $data['metadata'] ?? []
);
}
}
// Usage:
$response = $this->apiClient->get('example_api', '/users/1');
$user = UserResponse::fromApiResponse(json_decode($response->getBody(), true));
Extend the client to handle retries (e.g., using GuzzleHttp\RetryMiddleware):
# config/packages/sinevar_age_api.yaml
sinevar_age_api:
clients:
example_api:
middleware:
- 'retry'
- 'timeout'
Dispatch events before/after API calls:
// src/EventListener/ApiRequestListener.php
class ApiRequestListener implements KernelEventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
KernelEvents::REQUEST => ['onKernelRequest', 100],
];
}
public function onKernelRequest(RequestEvent $event): void
{
if ($event->isMainRequest()) {
$this->apiClient->addHeader('X-Request-ID', uniqid());
}
}
}
Configuration Overrides
sinevar_age_api.yaml is merged correctly with environment variables.%env(API_TOKEN)% for secrets, but validate the .env file is loaded.Error Handling
ClientException for HTTP errors (4xx/5xx). Catch and log these explicitly:
try {
$this->apiClient->get('example_api', '/invalid');
} catch (ClientException $e) {
$statusCode = $e->getResponse()->getStatusCode();
if ($statusCode === 404) {
// Handle not found
}
}
Middleware Conflicts
retry) may not be auto-loaded. Verify the middleware key in config:
sinevar_age_api:
clients:
example_api:
middleware:
- 'Sinevar\AGEApiBundle\Middleware\RetryMiddleware'
Deprecation Warnings
$this->apiClient->getClient()->getConfig()['debug'] = true;
$response = $this->apiClient->get('example_api', '/users');
$this->logger->debug('API Response', [
'status' => $response->getStatusCode(),
'body' => $response->getBody()->getContents(),
]);
Custom Clients
Implement ApiClientInterface for non-Guzzle HTTP clients:
class CustomApiClient implements ApiClientInterface
{
public function get(string $clientName, string $endpoint): ResponseInterface
{
// Custom logic (e.g., use Symfony Panther)
}
}
Register as a service:
services:
Sinevar\AGEApiBundle\Client\ApiClientInterface: '@custom_api_client'
Response Transformers
Add a response_transformer key to auto-transform responses:
sinevar_age_api:
clients:
example_api:
response_transformer: 'App\Transformer\JsonTransformer'
Implement Sinevar\AGEApiBundle\Transformer\ResponseTransformerInterface.
Authentication Plugins Extend auth types (e.g., OAuth2) by creating a custom auth provider:
class OAuth2AuthProvider implements AuthProviderInterface
{
public function getHeaders(): array
{
return ['Authorization' => 'Bearer ' . $this->getToken()];
}
}
Bind in config:
sinevar_age_api:
clients:
oauth_api:
auth:
type: 'oauth2'
provider: 'App\Auth\OAuth2AuthProvider'
How can I help you explore Laravel packages today?