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

bnnvara/graphql-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the bundle via Composer:

    composer require bnnvara/graphql-bundle
    

    Enable the bundle in config/bundles.php:

    return [
        // ...
        Bnnvara\GraphQLBundle\BnnvaraGraphQLBundle::class => ['all' => true],
    ];
    
  2. Basic Configuration Define a minimal config/packages/bnnvara_graphql.yaml:

    bnnvara_graphql:
        schema:
            query: 'App\\GraphQL\\Query\\Query'
            mutation: 'App\\GraphQL\\Mutation\\Mutation'
        debug: '%kernel.debug%'
    
  3. First Query Create a simple resolver (e.g., src/GraphQL/Query/Query.php):

    namespace App\GraphQL\Query;
    
    use GraphQL\Type\Definition\Type;
    use GraphQL\Type\Definition\ResolveInfo;
    
    class Query
    {
        public function hello()
        {
            return 'World';
        }
    }
    

    Define a schema in config/graphql/schema.graphqls:

    type Query {
        hello: String
    }
    

    Test via HTTP:

    curl -X POST http://your-app/_graphql \
        -H "Content-Type: application/json" \
        -d '{"query": "{ hello }"}'
    

Implementation Patterns

Resolver Workflows

  1. Dependency Injection Use Symfony’s DI to inject services into resolvers:

    use Symfony\Component\HttpKernel\KernelInterface;
    
    class Query
    {
        public function __construct(private KernelInterface $kernel) {}
    
        public function env()
        {
            return $this->kernel->getEnvironment();
        }
    }
    
  2. Input Types Define input types in src/GraphQL/Type/Input/InputType.php:

    namespace App\GraphQL\Type\Input;
    
    use GraphQL\Type\Definition\Type;
    
    class CreateUserInput
    {
        public function build(): Type
        {
            return Type::nonNull(Type::string());
        }
    }
    
  3. Mutations Implement mutations in src/GraphQL/Mutation/Mutation.php:

    class Mutation
    {
        public function createUser(string $name)
        {
            // Logic here
            return ['name' => $name];
        }
    }
    
  4. Schema Stitching Extend the schema dynamically via BnnvaraGraphQLBundle::extendSchema() in a compiler pass:

    use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
    use Symfony\Component\DependencyInjection\ContainerBuilder;
    
    class GraphQLSchemaPass implements CompilerPassInterface
    {
        public function process(ContainerBuilder $container)
        {
            $definition = $container->findDefinition('bnnvara_graphql.schema');
            $definition->addMethodCall('extendSchema', [/* custom schema */]);
        }
    }
    

Integration Tips

  1. Symfony Forms Use Symfony\Component\Form\FormFactoryInterface in resolvers to validate input:

    use Symfony\Component\Form\FormFactoryInterface;
    
    class Mutation
    {
        public function __construct(private FormFactoryInterface $formFactory) {}
    
        public function createUser(array $input)
        {
            $form = $this->formFactory->createNamedBuilder('user', UserType::class, $input);
            if ($form->isSubmitted() && $form->isValid()) {
                return $form->getData();
            }
            throw new \RuntimeException('Invalid input');
        }
    }
    
  2. Doctrine ORM Inject Doctrine\ORM\EntityManagerInterface for database operations:

    use Doctrine\ORM\EntityManagerInterface;
    
    class Query
    {
        public function __construct(private EntityManagerInterface $em) {}
    
        public function users()
        {
            return $this->em->getRepository(User::class)->findAll();
        }
    }
    
  3. Authentication Use Symfony’s security component to restrict resolvers:

    use Symfony\Component\Security\Core\Security;
    
    class Query
    {
        public function __construct(private Security $security) {}
    
        public function secret()
        {
            if (!$this->security->isGranted('ROLE_ADMIN')) {
                throw new \RuntimeException('Unauthorized');
            }
            return 'Secret data';
        }
    }
    
  4. Caching Enable schema caching in config/packages/bnnvara_graphql.yaml:

    bnnvara_graphql:
        schema:
            cache: true
    

Gotchas and Tips

Pitfalls

  1. Schema Validation

    • Issue: Schema mismatches between .graphqls and PHP resolvers cause runtime errors.
    • Fix: Use php bin/console bnnvara:graphql:validate to check schema consistency.
  2. Circular Dependencies

    • Issue: Resolvers with circular DI dependencies (e.g., Query injecting Mutation and vice versa) fail silently.
    • Fix: Refactor to use interfaces or lazy-loading services.
  3. Debugging

    • Issue: Debug mode (debug: true) logs are verbose and may clutter production.
    • Fix: Use BNNVARA_GRAPHQL_DEBUG env var to toggle dynamically:
      debug: '%env(bool:BNNVARA_GRAPHQL_DEBUG)%'
      
  4. Performance

    • Issue: N+1 queries in resolvers degrade performance.
    • Fix: Use Doctrine\ORM\QueryBuilder with join() or DQL for batch loading.

Debugging Tips

  1. GraphQL Playground Enable the built-in playground for interactive testing:

    bnnvara_graphql:
        playground: true
    

    Access at /_graphql-playground.

  2. Logging Configure Monolog to log GraphQL errors:

    monolog:
        handlers:
            graphql:
                type: stream
                path: "%kernel.logs_dir%/graphql.log"
                level: error
                channels: ["graphql"]
    
  3. Error Handling Customize error formatting in config/packages/bnnvara_graphql.yaml:

    bnnvara_graphql:
        error_formatter: App\GraphQL\ErrorFormatter
    

    Implement App\GraphQL\ErrorFormatter to extend GraphQL\Error\Formatter\ErrorFormatterInterface.


Extension Points

  1. Custom Directives Register directives via a compiler pass:

    $definition->addMethodCall('addDirective', [
        'deprecated',
        new Reference('App\GraphQL\Directive\DeprecatedDirective')
    ]);
    
  2. Middleware Add middleware to the GraphQL pipeline:

    bnnvara_graphql:
        middleware:
            - App\GraphQL\Middleware\AuthMiddleware
            - App\GraphQL\Middleware\LoggingMiddleware
    
  3. Validation Rules Extend input validation with custom rules:

    use GraphQL\Validator\Rules;
    
    class CustomRules extends Rules
    {
        public function validateCustomRule()
        {
            // Custom logic
        }
    }
    

    Register in config/packages/bnnvara_graphql.yaml:

    bnnvara_graphql:
        validator:
            rules: ['@App\GraphQL\Validator\CustomRules']
    
  4. Subscription Support Enable subscriptions via Mercure or custom logic:

    bnnvara_graphql:
        subscriptions:
            enabled: true
            hub_url: '%env(MERCURE_HUB_URL)%'
    
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.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware