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

Graphqlite Bundle Laravel Package

dyonis/graphqlite-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Bundle

    composer require thecodingmachine/graphqlite-bundle
    

    Register the bundle in config/bundles.php (Symfony auto-discovers it, but explicit registration ensures compatibility):

    return [
        // ...
        TheCodingMachine\GraphQLite\Bundle\GraphQLiteBundle::class => ['all' => true],
    ];
    
  2. Configure the Bundle Add basic config in config/packages/graphqlite.yaml:

    graphqlite:
        schema:
            query: 'App\\GraphQL\\Query'
            mutation: 'App\\GraphQL\\Mutation'
        debug: '%kernel.debug%'
    
  3. Define Your First Schema Create a Query class (e.g., src/GraphQL/Query.php):

    namespace App\GraphQL;
    
    use TheCodingMachine\GraphQLite\Annotations\Query;
    use TheCodingMachine\GraphQLite\Types\TypeResolverInterface;
    
    class Query
    {
        /**
         * @Query()
         */
        public function hello(): string
        {
            return 'World';
        }
    }
    
  4. Access the GraphQL Endpoint Run the dev server and query at:

    http://localhost:8000/graphql
    

    Example query:

    query {
        hello
    }
    

First Use Case: Fetching Data from Doctrine

  1. Annotate a Query to Fetch Entities

    use App\Entity\User;
    use Doctrine\ORM\EntityManagerInterface;
    use TheCodingMachine\GraphQLite\Annotations\Query;
    
    class Query
    {
        private $em;
    
        public function __construct(EntityManagerInterface $em)
        {
            $this->em = $em;
        }
    
        /**
         * @Query()
         */
        public function user(int $id): User
        {
            return $this->em->getRepository(User::class)->find($id);
        }
    }
    
  2. Query the Entity

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

Implementation Patterns

1. Type Resolvers and Custom Types

  • Auto-Discovery: GraphQLite auto-discovers Doctrine entities as types. Annotate fields to control output:

    /**
     * @Query()
     */
    public function user(int $id): User
     {
         return $this->em->find(User::class, $id);
     }
    

    Outputs all public properties of User by default.

  • Custom Types: Extend TypeResolverInterface for complex types:

    use TheCodingMachine\GraphQLite\Types\TypeResolverInterface;
    
    class CustomTypeResolver implements TypeResolverInterface
    {
        public function getType(string $typeName): ?string
        {
            return match ($typeName) {
                'App\\GraphQL\\CustomType' => 'CustomGraphQLType',
                default => null,
            };
        }
    }
    

    Register in config/packages/graphqlite.yaml:

    graphqlite:
        type_resolver: App\GraphQL\CustomTypeResolver
    

2. Mutations and Input Types

  • Define a Mutation:

    use TheCodingMachine\GraphQLite\Annotations\Mutation;
    use TheCodingMachine\GraphQLite\Annotations\InputType;
    
    class Mutation
    {
        /**
         * @Mutation()
         */
        public function createUser(string $name, string $email): User
        {
            $user = new User();
            $user->setName($name);
            $user->setEmail($email);
            $this->em->persist($user);
            $this->em->flush();
            return $user;
        }
    }
    

    Query:

    mutation {
        createUser(name: "John", email: "[email protected]") {
            id
            name
        }
    }
    
  • Input Types: Use @InputType for complex inputs:

    #[InputType]
    class CreateUserInput
    {
        public string $name;
        public string $email;
    }
    
    /**
     * @Mutation()
     */
    public function createUser(CreateUserInput $input): User
    {
        // ...
    }
    

3. Integration with Symfony Services

  • Dependency Injection: Inject any Symfony service into your Query/Mutation classes:

    use Symfony\Component\Mailer\MailerInterface;
    
    class Query
    {
        public function __construct(private MailerInterface $mailer) {}
    
        /**
         * @Query()
         */
        public function sendTestEmail(): bool
        {
            $this->mailer->send(...);
            return true;
        }
    }
    
  • Event Listeners: Listen to GraphQL events (e.g., GraphQLiteEvents::EXECUTE_QUERY):

    use TheCodingMachine\GraphQLite\Event\ExecuteQueryEvent;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    
    class GraphQLSubscriber implements EventSubscriberInterface
    {
        public static function getSubscribedEvents(): array
        {
            return [
                'graphqlite.execute_query' => 'onExecuteQuery',
            ];
        }
    
        public function onExecuteQuery(ExecuteQueryEvent $event)
        {
            // Log or modify the query
        }
    }
    

4. Pagination and Collections

  • Cursor-Based Pagination:
    use TheCodingMachine\GraphQLite\Annotations\Query;
    use TheCodingMachine\GraphQLite\Types\Type;
    use TheCodingMachine\GraphQLite\Types\CursorConnection;
    
    /**
     * @Query()
     */
    public function users(int $first = 10, ?string $after = null): CursorConnection
    {
        $query = $this->em->createQueryBuilder()
            ->select('u')
            ->from(User::class, 'u')
            ->orderBy('u.id');
    
        return new CursorConnection(
            $query->getQuery(),
            $first,
            $after,
            new Type(User::class)
        );
    }
    
    Query:
    query {
        users(first: 5) {
            edges {
                node {
                    id
                    name
                }
            }
            pageInfo {
                hasNextPage
            }
        }
    }
    

5. Authentication and Authorization

  • Middleware for Auth:
    # config/packages/graphqlite.yaml
    graphqlite:
        middleware:
            - App\GraphQL\Middleware\AuthMiddleware
    
    Example middleware:
    use TheCodingMachine\GraphQLite\Middleware\MiddlewareInterface;
    use TheCodingMachine\GraphQLite\Execution\ExecutionContext;
    
    class AuthMiddleware implements MiddlewareInterface
    {
        public function handle(ExecutionContext $context): void
        {
            if (!$context->getRequest()->getUser()) {
                throw new \RuntimeException('Unauthorized');
            }
        }
    }
    

Gotchas and Tips

Pitfalls

  1. Circular References in Types

    • GraphQLite may fail to resolve circular references (e.g., User has-many Posts, Post belongs-to User).
    • Fix: Use @IgnoreType or manually define types:
      use TheCodingMachine\GraphQLite\Annotations\IgnoreType;
      
      #[IgnoreType]
      class User {}
      
  2. Doctrine Lazy Loading

    • Eager-load associations to avoid "uninitialized property" errors:
      $user = $this->em->find(User::class, $id, ['posts' => 'posts']);
      
  3. Type Mismatches

    • GraphQLite is strict about return types. Ensure annotations match actual return types:
      // ❌ Fails if `find()` returns `null`
      /**
       * @Query()
       * @return User
       */
      public function user(int $id): ?User
      {
          return $this->em->find(User::class, $id);
      }
      
  4. Caching Headaches

    • Disable caching during development (debug: true in config) to avoid stale schemas:
      graphqlite:
          debug: true
      

Debugging Tips

  1. Enable Debug Mode Set debug: true in config to see:

    • Schema introspection.
    • Query execution logs.
  2. Inspect the Schema Query the __schema introspection endpoint:

    query {
        __schema {
            types {
                name
            }
        }
    }
    
  3. Use graphqlite:dump-schema Dump the schema to a file for offline inspection:

    php bin/console graphqlite:dump-schema
    
  4. Validate Annotations Run the validator to catch annotation errors:

    php bin/console graphql
    
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.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle