Installation Add the bundle via Composer:
composer require ciloe/graphql-client-bundle
Enable the bundle in config/bundles.php:
return [
// ...
Ciloe\GraphQLClientBundle\CiloeGraphQLClientBundle::class => ['all' => true],
];
Basic Configuration
Configure the client in config/packages/ciloe_graphql_client.yaml:
ciloe_graphql_client:
endpoint: 'https://your-graphql-endpoint.com/graphql'
headers:
Authorization: 'Bearer YOUR_TOKEN'
First Query Inject the client service and execute a query:
use Ciloe\GraphQLClientBundle\Service\GraphQLClient;
class MyController extends AbstractController
{
public function __construct(private GraphQLClient $client)
{
}
public function queryExample()
{
$query = '
query {
user(id: 1) {
name
email
}
}
';
$result = $this->client->query($query);
return $this->json($result);
}
}
Direct Query Execution
Use the query() method for one-off requests:
$result = $client->query($queryString);
Named Queries (Recommended for Reusability)
Define queries in YAML/JSON files (e.g., config/graphql/queries/user.yaml):
user:
query: 'query { user(id: $id) { name } }'
variables: { id: 1 }
Load and execute via the service:
$result = $client->queryFromFile('user', ['id' => 1]);
Variable Binding Pass variables dynamically:
$query = 'query GetUser($id: ID!) { user(id: $id) { name } }';
$result = $client->query($query, ['id' => 2]);
Mutation Support
Use the mutate() method for mutations:
$mutation = '
mutation CreateUser($input: UserInput!) {
createUser(input: $input) { id }
}
';
$result = $client->mutate($mutation, ['input' => ['name' => 'John']]);
Dependency Injection
Inject GraphQLClient into controllers, services, or commands:
public function __construct(private GraphQLClient $client) {}
Event Listeners/Subscribers
Extend functionality by listening to graphql.client.query events:
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Ciloe\GraphQLClientBundle\Event\QueryEvent;
class GraphQLLoggerSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [QueryEvent::NAME => 'onQuery'];
}
public function onQuery(QueryEvent $event)
{
// Log or modify the query/variables
}
}
Caching Strategies Leverage the built-in cache service:
# config/packages/ciloe_graphql_client.yaml
ciloe_graphql_client:
cache:
enabled: true
provider: 'cache.app' # Symfony cache service ID
Cache queries automatically by normalizing variables:
$client->query($query, ['id' => 1]); // Cached with key: "query_hash:id:1"
Error Handling Wrap queries in try-catch blocks:
try {
$result = $client->query($query);
} catch (GraphQLClientException $e) {
// Handle errors (e.g., network issues, GraphQL errors)
$this->addFlash('error', $e->getMessage());
}
Deprecated Package
webonyx/graphql-php.Cache Key Collisions
DateTime) may cause issues.$client->setCacheKeyGenerator(function ($query, $variables) {
return md5($query . json_encode($variables, JSON_UNESCAPED_UNICODE));
});
Header Injection Risks
%env% or parameter bags:
headers:
Authorization: '%env(API_TOKEN)%'
No Built-in Retry Logic
use Symfony\Component\Retry\Retry;
$retry = new Retry(3, 100); // 3 retries, 100ms delay
$result = $retry->retry(function () use ($client, $query) {
return $client->query($query);
});
Enable Verbose Logging
Add to config/packages/monolog.yaml:
handlers:
graphql:
type: stream
path: '%kernel.logs_dir%/graphql.log'
level: debug
channels: ['graphql']
Then enable the channel in the bundle config:
ciloe_graphql_client:
logging:
enabled: true
channel: 'graphql'
Inspect Raw Responses
Use the rawQuery() method to bypass processing:
$response = $client->rawQuery($query);
// Dump the full HTTP response
file_put_contents('debug.graphql', print_r($response, true));
Variable Validation The bundle doesn’t validate variables against the schema. Use a tool like GraphQL Playground or Altair to test queries first.
Custom HTTP Client
Override the default GuzzleHttp\Client by binding a new service:
# config/services.yaml
services:
Ciloe\GraphQLClientBundle\Service\GraphQLClient:
arguments:
$httpClient: '@your_custom.http_client'
Query Preprocessing Add middleware to modify queries/variables before execution:
$client->addMiddleware(function ($query, $variables) {
// Add auth headers dynamically
$variables['authToken'] = $this->getAuthToken();
return [$query, $variables];
});
Response Transformation Extend the response parser to normalize data:
$client->setResponseParser(function ($response) {
$data = json_decode($response->getBody(), true);
return $this->transformResponse($data);
});
Schema Introspection
The bundle lacks introspection tools. Use a separate library like graphql-php for schema-aware development.
How can I help you explore Laravel packages today?