Install the Bundle
composer require idci/graphql-client-bundle
Configure Guzzle HTTP Clients
Define clients in config/packages/eight_points_guzzle.yaml:
eight_points_guzzle:
clients:
my_graphql_client:
base_url: 'https://api.example.com/graphql'
timeout: 10
Register GraphQL Clients
Add to config/packages/idci_graphql_client.yaml:
idci_graphql_client:
clients:
my_graphql_client:
http_client: 'eight_points_guzzle.client.my_graphql_client'
cache_pool: 'cache.app' # Optional: Link to Symfony cache pool
First Query Inject the registry and execute a query:
use IDCI\Bundle\GraphQLClientBundle\Client\Registry;
public function __construct(private Registry $registry) {}
public function fetchData()
{
$client = $this->registry->get('my_graphql_client');
$result = $client->query('query { user(id: 1) { name } }');
return $result->toArray();
}
// In a controller or service
$query = [
'query' => '
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
}
}
',
'variables' => ['id' => 1]
];
$result = $client->query($query);
$user = $result->get('user');
Use the Query Builder to construct queries programmatically:
use IDCI\Bundle\GraphQLClientBundle\Query\Builder;
// Build a query
$query = (new Builder())
->select('user', ['id', 'name'])
->where('id', 1)
->build();
// Execute
$result = $client->query($query);
Leverage Symfony’s cache pools for repeated queries:
# config/packages/idci_graphql_client.yaml
idci_graphql_client:
clients:
my_graphql_client:
http_client: 'eight_points_guzzle.client.my_graphql_client'
cache_pool: 'cache.my_cache_one' # Cache for 10 minutes
cache_ttl: 600
Cache Invalidation:
// Manually invalidate cache for a query
$client->invalidateCache('query { user(id: 1) { name } }');
Wrap queries in try-catch blocks:
try {
$result = $client->query($query);
} catch (\IDCI\Bundle\GraphQLClientBundle\Exception\GraphQLException $e) {
// Handle GraphQL errors (e.g., validation, network)
$errors = $e->getErrors();
$this->addFlash('error', 'GraphQL Error: ' . $e->getMessage());
}
Use cursor-based pagination with the Query Builder:
$query = (new Builder())
->select('users', ['id', 'name'])
->limit(10)
->after('cursor_value') // For cursor-based pagination
->build();
$result = $client->query($query);
Fetch multiple resources in a single query:
$query = (new Builder())
->select('users', ['id', 'name'])
->whereIn('id', [1, 2, 3])
->build();
$result = $client->query($query);
$users = $result->get('users');
Cache Key Collisions
Guzzle Client Timeouts
eight_points_guzzle:
eight_points_guzzle:
clients:
my_graphql_client:
timeout: 30 # Increase timeout in seconds
Case-Sensitive Query Handling
Cache Pool Misconfiguration
cache_pool is not defined in Symfony’s cache config, queries will fail silently. Verify:
framework:
cache:
pools:
cache.my_cache_one:
adapter: cache.adapter.apcu
Enable Guzzle Debugging Add middleware to log requests:
$client = $this->registry->get('my_graphql_client');
$client->getHttpClient()->getEmitter()->attach(
new \GuzzleHttp\Middleware::tap(function ($request) {
\Log::debug('GraphQL Request:', ['url' => (string) $request->getUri(), 'body' => $request->getBody()]);
})
);
Inspect Raw Responses
Use toArray() or toJson() to debug:
$result = $client->query($query);
\Log::debug('Raw Response:', $result->toJson());
Query Builder Validation Validate queries before execution:
$query = (new Builder())->select('user', ['id']);
if (!$query->isValid()) {
throw new \RuntimeException('Invalid query: ' . $query->getErrors());
}
Custom Response Decorators Extend the response object to add domain-specific logic:
use IDCI\Bundle\GraphQLClientBundle\Response;
class CustomResponse extends Response
{
public function getUserData(): array
{
return $this->get('user') ?: [];
}
}
Register in services.yaml:
services:
IDCI\Bundle\GraphQLClientBundle\Response: '@App\CustomResponse'
Middleware for Authentication Add headers dynamically:
$client->getHttpClient()->getEmitter()->attach(
new \GuzzleHttp\Middleware::mapRequest(function ($request) {
$request = $request->withHeader('Authorization', 'Bearer ' . $this->authToken);
return $request;
})
);
Custom Cache Providers
Implement IDCI\Bundle\GraphQLClientBundle\Cache\CacheProviderInterface for non-Symfony caches (e.g., Redis):
class RedisCacheProvider implements CacheProviderInterface
{
public function get($key): ?string
{
return $this->redis->get($key);
}
public function set($key, $value, int $ttl): void
{
$this->redis->setex($key, $ttl, $value);
}
}
Bind in services.yaml:
services:
App\Cache\RedisCacheProvider:
tags: ['idci_graphql_client.cache_provider']
How can I help you explore Laravel packages today?