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

youshido/graphql

A PHP GraphQL library for building schemas and executing queries with a type-safe, object-oriented API. Define types, fields, resolvers, and middleware in code, with support for input validation, custom scalars, and introspection for PHP apps.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup in Laravel

  1. Installation

    composer require youshido/graphql
    

    Add to config/app.php under providers:

    YouShido\GraphQL\GraphQLServiceProvider::class,
    
  2. Define a Basic Schema Create a schema class (e.g., app/GraphQL/Schema.php):

    use YouShido\GraphQL\Type\ObjectType;
    use YouShido\GraphQL\Type\StringType;
    use YouShido\GraphQL\Schema;
    
    $schema = new Schema();
    $schema->type('Query', new class extends ObjectType {
        protected function fields(): array {
            return [
                'hello' => fn() => new StringType('Hello, GraphQL!')
            ];
        }
    });
    
  3. Register Schema in Laravel In AppServiceProvider@boot():

    GraphQL::schema($schema);
    
  4. First Query Use a middleware or route to handle GraphQL requests:

    Route::post('/graphql', function (Request $request) {
        return GraphQL::execute($request->input('query'));
    });
    

    Test with:

    query {
      hello
    }
    

First Use Case: Querying a Model

Define a UserType and resolver:

$schema->type('User', new class extends ObjectType {
    protected function fields(): array {
        return [
            'name' => fn() => new StringType($this->rootValue->name),
            'email' => fn() => new StringType($this->rootValue->email)
        ];
    }
});

$schema->type('Query', new class extends ObjectType {
    protected function fields(): array {
        return [
            'user' => fn() => new UserType(User::find(1))
        ];
    }
});

Implementation Patterns

Schema-First Workflow

  1. Define Types First Model your domain as GraphQL types before writing resolvers. Example:

    $schema->type('Post', new class extends ObjectType {
        protected function config(): array {
            return [
                'description' => 'A blog post'
            ];
        }
        protected function fields(): array {
            return [
                'title' => fn() => new StringType($this->rootValue->title),
                'content' => fn() => new StringType($this->rootValue->content)
            ];
        }
    });
    
  2. Compose Queries/Mutations Use ObjectType for root queries/mutations:

    $schema->type('Query', new class extends ObjectType {
        protected function fields(): array {
            return [
                'posts' => fn() => new ListType(PostType::class, Post::all()),
                'createPost' => fn() => new MutationType(/* ... */)
            ];
        }
    });
    
  3. Reuse Types with Interfaces/Unions

    $schema->type('Node', new InterfaceType([
        'resolveType' => fn($value) => $value instanceof User ? 'User' : 'Post'
    ]));
    $schema->type('User', new class extends ObjectType {
        protected function interfaces(): array { return ['Node']; }
    });
    

Integration with Laravel

  1. Dependency Injection Resolve Laravel services in resolvers:

    'posts' => fn() => new ListType(PostType::class, app(PostRepository::class)->all())
    
  2. Authentication Use middleware to attach context:

    GraphQL::middleware(function ($request, $next) {
        $request->merge(['user' => auth()->user()]);
        return $next($request);
    });
    
  3. Validation Leverage Laravel’s validation in input types:

    $schema->type('CreatePostInput', new InputObjectType([
        'fields' => [
            'title' => ['type' => new NonNullType(StringType::of())],
            'content' => ['type' => new NonNullType(StringType::of())]
        ],
        'validate' => function ($input) {
            $validator = Validator::make($input, [
                'title' => 'required|max:255',
                'content' => 'required'
            ]);
            if ($validator->fails()) {
                throw new ValidationError($validator->errors());
            }
        }
    ]));
    

Mutation Patterns

  1. Define a Mutation

    $schema->type('Mutation', new class extends ObjectType {
        protected function fields(): array {
            return [
                'createUser' => fn() => new FieldType([
                    'type' => new UserType(),
                    'args' => ['input' => new Argument(['type' => new NonNullType(CreateUserInputType::of())])],
                    'resolve' => fn($root, $args) => User::create($args['input'])
                ])
            ];
        }
    });
    
  2. Optimistic UI Return resolved data immediately for client-side updates:

    'resolve' => fn($root, $args) => [
        'user' => User::create($args['input']),
        'clientMutationId' => $args['input']['clientMutationId']
    ]
    

Gotchas and Tips

Common Pitfalls

  1. Circular References Avoid infinite loops in resolvers. Use lazy() for deferred resolution:

    'author' => fn() => new LazyType(fn() => new UserType($this->rootValue->author))
    
  2. Type Mismatches Ensure resolver return types match declared field types. Use NonNullType for required fields:

    'id' => fn() => new NonNullType(IDType::of())
    
  3. Performance

    • N+1 Queries: Use eagerLoad() or with() in resolvers:
      'posts' => fn() => new ListType(PostType::class, Post::with('author')->get())
      
    • Pagination: Implement cursor-based pagination for large datasets.
  4. Deprecated API The package is last updated in 2019. Check for:

    • Compatibility with newer PHP/Laravel versions.
    • Alternatives like graphql-php/graphql for active maintenance.

Debugging

  1. Enable Introspection Add to schema config:

    $schema->config(['introspection' => true]);
    

    Query schema via:

    query IntrospectionQuery {
      __schema {
        types {
          name
          kind
        }
      }
    }
    
  2. Logging Execution Use a custom ExecutionStrategy to log queries:

    GraphQL::executionStrategy(new class extends ExecutionStrategy {
        public function execute(ExecutionContext $context) {
            Log::debug('GraphQL Query:', ['query' => $context->getQuery()]);
            return parent::execute($context);
        }
    });
    
  3. Validation Errors Catch ValidationError in resolvers:

    try {
        return User::create($args['input']);
    } catch (ValidationError $e) {
        throw new GraphQLException($e->getMessage());
    }
    

Extension Points

  1. Custom Scalars Extend ScalarType for custom types (e.g., DateTime):

    $schema->type('DateTime', new class extends ScalarType {
        public function serialize($value) {
            return $value->format('Y-m-d H:i:s');
        }
        public function parseValue($value) {
            return new DateTime($value);
        }
    });
    
  2. Middleware Pipeline Add pre/post-processing:

    GraphQL::middleware(function ($request, $next) {
        // Pre-processing
        $response = $next($request);
        // Post-processing
        return $response;
    });
    
  3. Plugin System Use Schema::extend() to add global functionality:

    Schema::extend(function ($schema) {
        $schema->type('Query')->fields['time'] = fn() => new StringType(now()->toIso8601String());
    });
    

Laravel-Specific Tips

  1. Caching Schema Cache the compiled schema in Laravel’s cache:

    $schema = Cache::remember('graphql.schema', now()->addHours(1), function() {
        return new Schema(/* ... */);
    });
    
  2. Testing Use GraphQL::execute() in tests:

    $result = GraphQL::execute('query { hello }');
    $this->assertEquals('Hello, GraphQL!', $result->data['hello']);
    
  3. API Resources Convert Laravel ApiResources to GraphQL types:

    $schema->type('UserResource', new class extends ObjectType {
        protected function fields(): array {
            return collect
    
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky