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 Bundle Laravel Package

overblog/graphql-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Bundle

    composer require overblog/graphql-bundle
    

    Add to config/bundles.php:

    return [
        // ...
        Overblog\GraphQLBundle\OverblogGraphQLBundle::class => ['all' => true],
    ];
    
  2. Configure Basic Schema Create a schema configuration file (e.g., config/graphql/schema.yaml):

    schema:
        query: App\\GraphQL\\Query
        mutation: App\\GraphQL\\Mutation
        subscription: App\\GraphQL\\Subscription
    
  3. Define Your First Query Create a Query class in src/GraphQL/Query.php:

    namespace App\GraphQL;
    
    use GraphQL\Type\Definition\Type;
    use Overblog\GraphQLBundle\Definition\Resolver\ResolverInterface;
    
    class Query
    {
        public function hello()
        {
            return 'world';
        }
    }
    
  4. Test the Endpoint Visit /graphql in your browser or use a client like Postman/GraphQL Playground with the query:

    query {
        hello
    }
    

First Use Case: Fetching Data from Doctrine

  1. Define a Type Create a UserType in src/GraphQL/Type/UserType.php:

    namespace App\GraphQL\Type;
    
    use App\Entity\User;
    use GraphQL\Type\Definition\Type;
    use Overblog\GraphQLBundle\Definition\Type\ObjectType;
    
    class UserType extends ObjectType
    {
        protected function buildFields(): array
        {
            return [
                'id' => Type::id(),
                'name' => Type::string(),
            ];
        }
    
        public function getName(): string
        {
            return 'User';
        }
    
        public function getEntityClass(): string
        {
            return User::class;
        }
    }
    
  2. Resolve the Type in Query Update Query.php:

    use App\GraphQL\Type\UserType;
    use GraphQL\Type\Definition\Type;
    
    class Query
    {
        public function user(UserType $type, int $id)
        {
            return $this->getDoctrine()->getRepository(User::class)->find($id);
        }
    }
    
  3. Query in GraphQL Playground

    query {
        user(id: 1) {
            id
            name
        }
    }
    

Implementation Patterns

Workflows

1. Type-Driven Development

  • Pattern: Define types first, then resolvers. Use ObjectType, InputType, and InterfaceType to model your domain.
  • Example:
    // src/GraphQL/Type/PostType.php
    class PostType extends ObjectType
    {
        protected function buildFields(): array
        {
            return [
                'title' => Type::string(),
                'author' => new UserType(),
                'comments' => Type::listOf(new CommentType()),
            ];
        }
    }
    

2. Resolver Caching

  • Pattern: Cache resolvers for performance. Use Symfony’s cache system or the bundle’s built-in caching.
  • Example:
    # config/packages/overblog_graphql.yaml
    overblog_graphql:
        resolvers_cache: true
    

3. Input Types for Mutations

  • Pattern: Use InputType for mutations to validate input data.

  • Example:

    // src/GraphQL/Type/CreateUserInputType.php
    class CreateUserInputType extends InputType
    {
        protected function buildFields(): array
        {
            return [
                'name' => Type::nonNull(Type::string()),
                'email' => Type::nonNull(Type::string()),
            ];
        }
    }
    
  • Mutation:

    // src/GraphQL/Mutation.php
    class Mutation
    {
        public function createUser(CreateUserInputType $input)
        {
            $user = new User();
            $user->setName($input->getName());
            $user->setEmail($input->getEmail());
            $this->getDoctrine()->getManager()->persist($user);
            $this->getDoctrine()->getManager()->flush();
            return $user;
        }
    }
    

4. Relay Compliance

  • Pattern: Use GlobalIdType and NodeInterface for Relay-compatible nodes.
  • Example:
    // src/GraphQL/Type/UserType.php
    use Overblog\GraphQLBundle\Definition\Type\NodeInterface;
    
    class UserType extends ObjectType implements NodeInterface
    {
        public function getGlobalIdField(): string
        {
            return 'id';
        }
    }
    

Integration Tips

Doctrine Integration

  • Auto-Generate Types: Use the bundle’s doctrine:generate:types command to scaffold types from Doctrine entities.
    php bin/console overblog:graphql:doctrine:generate:types
    

Authentication

  • Pattern: Use Symfony’s security component to protect GraphQL endpoints.
    # config/routes.yaml
    graphql:
        path: /graphql
        methods: [GET, POST]
        defaults:
            _controller: overblog_graphql.controller.graphql_action
            _format: json
        requirements:
            _method: GET|POST
        role: ROLE_USER
    

Subscriptions

  • Pattern: Use Symfony Messenger for subscriptions.
    # config/packages/overblog_graphql.yaml
    overblog_graphql:
        subscriptions:
            messenger: true
    

Gotchas and Tips

Pitfalls

  1. Circular References

    • Issue: Forgetting to handle circular references in types (e.g., User has posts, Post has author).
    • Fix: Use @deprecated or lazy-loading with resolveValue():
      protected function resolveValue($value)
      {
          if ($value && $value->getAuthor()) {
              return $value;
          }
          return null;
      }
      
  2. Resolver Context

    • Issue: Not passing the resolver context (e.g., Doctrine, security token) to resolvers.
    • Fix: Inject dependencies via constructor or use the ResolverInterface:
      use Overblog\GraphQLBundle\Definition\Resolver\ResolverInterface;
      
      class Query implements ResolverInterface
      {
          private $doctrine;
      
          public function __construct(Doctrine $doctrine)
          {
              $this->doctrine = $doctrine;
          }
      
          public function user($root, array $args)
          {
              return $this->doctrine->getRepository(User::class)->find($args['id']);
          }
      }
      
  3. Batch Loading

    • Issue: N+1 queries when fetching related data.
    • Fix: Use DataLoader for batch loading:
      use Overblog\GraphQLBundle\DataLoader\DataLoader;
      
      class Query
      {
          private $dataLoader;
      
          public function __construct(DataLoader $dataLoader)
          {
              $this->dataLoader = $dataLoader;
          }
      
          public function user($root, array $args)
          {
              return $this->dataLoader->loadMany(User::class, [$args['id']]);
          }
      }
      

Debugging

  1. Enable Debug Mode

    # config/packages/overblog_graphql.yaml
    overblog_graphql:
        debug: true
    
    • Provides detailed error messages and query execution logs.
  2. GraphQL Playground

    • Use the built-in Playground at /graphql for interactive debugging.
  3. Logging

    • Enable logging for resolvers:
      overblog_graphql:
          logging: true
      

Tips

  1. Schema Stitching

    • Combine multiple schemas into one using Schema::merge():
      use GraphQL\Type\Schema;
      
      $schema = Schema::merge([
          new Schema([$queryType, $mutationType]),
          new Schema([$otherQueryType]),
      ]);
      
  2. Custom Directives

    • Add custom directives (e.g., @auth) for fine-grained access control:
      use Overblog\GraphQLBundle\Definition\Directive\Directive;
      
      class AuthDirective extends Directive
      {
          protected function configure()
          {
              $this->type('auth');
          }
      }
      
  3. Performance Optimization

    • Field Selection: Use resolveType() for interfaces/unions to optimize queries.
    • Pagination: Implement cursor-based pagination with ConnectionType:
      use Overblog\GraphQLBundle\Definition\Type\ConnectionType;
      
      class Query
      {
          public function posts(ConnectionType $connection)
          {
              return $connection->getConnection($this->getDoctrine()->getRepository(Post::class));
          }
      
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.
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver