Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Graphql Client Bundle Laravel Package

idci/graphql-client-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Bundle

    composer require idci/graphql-client-bundle
    
  2. 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
    
  3. 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
    
  4. 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();
    }
    

First Use Case: Fetching User Data

// 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');

Implementation Patterns

Query Builder Integration

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);

Caching Strategies

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 } }');

Error Handling

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());
}

Pagination

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);

Batch Loading

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');

Gotchas and Tips

Pitfalls

  1. Cache Key Collisions

    • Ensure query strings are deterministic (e.g., sort variables consistently).
    • Avoid dynamic fragments in cached queries unless explicitly handled.
  2. Guzzle Client Timeouts

    • Default timeouts may be too short for slow APIs. Configure in eight_points_guzzle:
      eight_points_guzzle:
          clients:
              my_graphql_client:
                  timeout: 30  # Increase timeout in seconds
      
  3. Case-Sensitive Query Handling

    • GraphQL queries are case-sensitive. Double-check query strings for typos.
  4. Cache Pool Misconfiguration

    • If 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
      

Debugging Tips

  1. 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()]);
        })
    );
    
  2. Inspect Raw Responses Use toArray() or toJson() to debug:

    $result = $client->query($query);
    \Log::debug('Raw Response:', $result->toJson());
    
  3. Query Builder Validation Validate queries before execution:

    $query = (new Builder())->select('user', ['id']);
    if (!$query->isValid()) {
        throw new \RuntimeException('Invalid query: ' . $query->getErrors());
    }
    

Extension Points

  1. 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'
    
  2. 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;
        })
    );
    
  3. 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']
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony
spatie/flare-daemon-runtime