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

youshido/graphql-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the bundle via Composer:

    composer require youshido/graphql-bundle
    

    Enable it in config/bundles.php:

    return [
        // ...
        Youshido\GraphQLBundle\YoushidoGraphQLBundle::class => ['all' => true],
    ];
    
  2. Basic Configuration Define a schema in config/packages/youshido_graphql.yaml:

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

    namespace App\GraphQL;
    
    use Youshido\GraphQL\Config\FieldConfig;
    use Youshido\GraphQL\Execution\ResolveInfo;
    use Youshido\GraphQL\Execution\Types\ResolveType;
    use Youshido\GraphQL\Execution\Types\ScalarType;
    use Youshido\GraphQL\Type\Definition\ObjectType;
    
    class Query
    {
        public function hello(FieldConfig $config, ResolveInfo $info)
        {
            return 'World';
        }
    }
    

    Test via HTTP:

    query {
        hello
    }
    
  4. Routing Add a route in config/routes.yaml:

    graphql:
        path: /graphql
        controller: youshido_graphql.controller.graphql
        methods: [GET, POST]
    

Implementation Patterns

Schema Design

  • Type Hierarchy Define types in dedicated classes (e.g., src/GraphQL/Type/UserType.php):

    namespace App\GraphQL\Type;
    
    use Youshido\GraphQL\Type\Definition\ObjectType;
    
    class UserType extends ObjectType
    {
        public function build($config)
        {
            $config->addField([
                'type' => 'String',
                'name' => 'name',
                'resolve' => function ($root) { return $root->name; },
            ]);
        }
    }
    
  • Resolvers Use dependency injection for services:

    use App\Service\UserService;
    
    class Query
    {
        private $userService;
    
        public function __construct(UserService $userService)
        {
            $this->userService = $userService;
        }
    
        public function user(FieldConfig $config, ResolveInfo $info)
        {
            return $this->userService->find($config->args['id']);
        }
    }
    

Workflows

  • Query/Mutation Separation Split logic into Query and Mutation classes for clarity. Example Mutation:

    class Mutation
    {
        public function createUser(FieldConfig $config, ResolveInfo $info)
        {
            $user = new User();
            $user->name = $config->args['name'];
            // Save logic...
            return $user;
        }
    }
    
  • Input Types Define input types for mutations:

    namespace App\GraphQL\Type;
    
    use Youshido\GraphQL\Type\Definition\InputObjectType;
    
    class CreateUserInputType extends InputObjectType
    {
        public function build($config)
        {
            $config->addField([
                'type' => 'String',
                'name' => 'name',
            ]);
        }
    }
    
  • Pagination Use Connection types for paginated queries:

    use Youshido\GraphQL\Type\Definition\ObjectType;
    use Youshido\GraphQL\Type\Relay\ConnectionType;
    
    class UserConnection extends ConnectionType
    {
        public function build($config)
        {
            $config->setType('UserType');
            $config->setResolveFn(function ($root, $args) {
                return User::paginate($args['first'], $args['after']);
            });
        }
    }
    

Integration Tips

  • Symfony Forms Bind GraphQL inputs to Symfony forms for validation:

    use Symfony\Component\Form\FormFactoryInterface;
    
    class Mutation
    {
        private $formFactory;
    
        public function __construct(FormFactoryInterface $formFactory)
        {
            $this->formFactory = $formFactory;
        }
    
        public function submitForm(FieldConfig $config, ResolveInfo $info)
        {
            $form = $this->formFactory->createBuilder()
                ->add('email', EmailType::class)
                ->getForm();
    
            $form->submit($config->args['input']);
            if ($form->isValid()) {
                // Process data...
            }
        }
    }
    
  • Doctrine ORM Use Doctrine repositories in resolvers:

    use Doctrine\ORM\EntityManagerInterface;
    
    class Query
    {
        private $em;
    
        public function __construct(EntityManagerInterface $em)
        {
            $this->em = $em;
        }
    
        public function users(FieldConfig $config, ResolveInfo $info)
        {
            return $this->em->getRepository(User::class)->findAll();
        }
    }
    

Gotchas and Tips

Pitfalls

  • Circular Dependencies Avoid circular references in type definitions (e.g., User referencing Post which references User). Use lazy loading or interfaces.

  • Scalar Type Mismatches Ensure resolver return types match declared GraphQL types. For example, returning null when a non-nullable type is expected will throw an error.

  • Debugging Resolvers Use var_dump($config->args) or var_dump($root) to inspect input data during development. Enable debug mode in config:

    youshido_graphql:
        debug: true
    
  • Deprecated API The package is last updated in 2019. Some Symfony 5+ features (e.g., attribute routing) may require workarounds or custom middleware.

Debugging

  • GraphQL Playground Access /graphql with debug mode enabled to use the built-in playground for interactive testing.

  • Error Handling Wrap resolvers in try-catch blocks to return user-friendly errors:

    public function riskyOperation(FieldConfig $config, ResolveInfo $info)
    {
        try {
            // ...
        } catch (\Exception $e) {
            throw new GraphQL\Error\GraphQLException($e->getMessage());
        }
    }
    
  • Logging Enable Monolog for GraphQL events:

    youshido_graphql:
        listeners:
            - App\GraphQL\Listener\LoggingListener
    

Configuration Quirks

  • Schema Auto-Discovery The bundle does not auto-discover types. Manually register types in build() methods or use a service to load them dynamically.

  • Custom Directives Register directives in the schema config:

    youshido_graphql:
        schema:
            directives:
                - App\GraphQL\Directive\DeprecatedDirective
    

Extension Points

  • Middleware Add middleware for authentication/authorization:

    use Youshido\GraphQL\Execution\Middleware\Middleware;
    
    class AuthMiddleware implements Middleware
    {
        public function execute($root, FieldConfig $config, ResolveInfo $info, callable $next)
        {
            if (!$this->isAuthenticated()) {
                throw new GraphQL\Error\GraphQLException('Unauthorized');
            }
            return $next($root, $config, $info);
        }
    }
    

    Register in config:

    youshido_graphql:
        middleware:
            - App\GraphQL\Middleware\AuthMiddleware
    
  • Custom Scalar Types Extend ScalarType for custom scalars (e.g., DateTime):

    namespace App\GraphQL\Type;
    
    use Youshido\GraphQL\Execution\Types\ScalarType;
    
    class DateTimeType extends ScalarType
    {
        public function __construct()
        {
            parent::__construct('DateTime');
        }
    
        public function serialize($value)
        {
            return $value->format(\DateTime::ATOM);
        }
    
        public function parseValue($value)
        {
            return new \DateTime($value);
        }
    }
    
  • Subscription Support Use ReactPHP for subscriptions (requires additional setup):

    youshido_graphql:
        schema:
            subscription: App\GraphQL\Subscription
        subscriptions:
            transport: react
    
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