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

webonyx/graphql-php

PHP implementation of the GraphQL specification, based on graphql-js. Build schemas, types, and execute queries/mutations in your PHP apps. Widely used, well-tested, and documented with examples and class reference.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:

    composer require webonyx/graphql-php
    
  2. Define a basic schema (e.g., schema.php):

    use GraphQL\Type\Definition\Type;
    use GraphQL\Type\Definition\ObjectType;
    use GraphQL\GraphQL;
    
    $queryType = new ObjectType([
        'name' => 'Query',
        'fields' => [
            'hello' => [
                'type' => Type::string(),
                'resolve' => fn() => 'World',
            ],
        ],
    ]);
    
    $schema = new \GraphQL\Schema([
        'query' => $queryType,
    ]);
    
    $query = '{ hello }';
    $result = GraphQL::executeQuery($schema, $query);
    
  3. Test with a simple query (e.g., via php artisan or a CLI script):

    echo $result->toString();
    

First Use Case: Querying Data

  • Use the GraphQL::executeQuery() method to run queries against your schema.
  • Example:
    $query = '
        query {
            user(id: 1) {
                name
                email
            }
        }
    ';
    $result = GraphQL::executeQuery($schema, $query);
    

Implementation Patterns

Schema Design

  1. Modular Schema Construction:

    • Define types (e.g., UserType, PostType) separately and compose them into the schema.
    • Example:
      $userType = new ObjectType([
          'name' => 'User',
          'fields' => [
              'id' => ['type' => Type::int()],
              'name' => ['type' => Type::string()],
          ],
      ]);
      
      $schema = new \GraphQL\Schema([
          'query' => new ObjectType([
              'name' => 'Query',
              'fields' => [
                  'user' => [
                      'type' => $userType,
                      'args' => ['id' => ['type' => Type::int()]],
                      'resolve' => fn($root, $args) => User::find($args['id']),
                  ],
              ],
          ]),
      ]);
      
  2. Reusing Types:

    • Use Type::listOf(), Type::nonNull(), and interfaces to avoid duplication.
    • Example:
      $commentType = new ObjectType([
          'name' => 'Comment',
          'fields' => [
              'text' => ['type' => Type::string()],
              'author' => ['type' => $userType],
          ],
      ]);
      

Resolver Patterns

  1. Data Fetching:

    • Use resolve functions to fetch data from databases, APIs, or other sources.
    • Example with Laravel Eloquent:
      'resolve' => fn($root, $args) => Post::with('author')->find($args['id']),
      
  2. Context Injection:

    • Pass context (e.g., auth, request) via GraphQL::executeQuery():
      $context = ['user' => auth()->user()];
      $result = GraphQL::executeQuery($schema, $query, null, null, $context);
      
  3. Optimized Resolvers:

    • Use ResolveInfo to optimize queries (e.g., select only requested fields):
      'resolve' => fn($post, $args, $context, $info) => {
          $fields = $info->fieldNodes[0]->selectionSet->selections;
          return Post::select(array_map(fn($f) => $f->name->value, $fields))->find($post->id);
      },
      

Integration with Laravel

  1. Middleware for GraphQL:

    • Use Laravel middleware to validate requests or inject context:
      Route::middleware(['graphql.auth'])->post('/graphql', function () {
          return response()->json(GraphQL::executeQuery($schema, $request->input('query')));
      });
      
  2. Service Providers:

    • Register the schema and middleware in AppServiceProvider:
      public function boot()
      {
          $this->app->singleton(\GraphQL\Schema::class, fn() => $this->app->make(\GraphQL\Schema::class));
      }
      
  3. Laravel Scout Integration:

    • Use GraphQL for search queries:
      'resolve' => fn($root, $args) => Post::search($args['query'])->get(),
      

Gotchas and Tips

Common Pitfalls

  1. Circular References:

    • Avoid circular references in resolvers (e.g., User resolving to Post which resolves back to User).
    • Use Type::nonNull() or lazy-loading to mitigate.
  2. N+1 Queries:

    • Always eager-load relationships in resolvers:
      'resolve' => fn($root, $args) => Post::with('author', 'comments')->find($args['id']),
      
  3. Type Mismatches:

    • Ensure resolver return types match the defined GraphQL type (e.g., return int for Type::int()).
  4. Performance:

    • Deeply nested queries can be slow. Use QueryComplexity or QueryDepth to limit them:
      DocumentValidator::addRule(new QueryComplexity(1000));
      

Debugging Tips

  1. Enable Error Reporting:

    • Use GraphQL::executeQuery() with debugFlag:
      $result = GraphQL::executeQuery($schema, $query, null, null, null, null, ['debugFlag' => true]);
      
  2. Introspection:

    • Use the __schema query to debug types:
      query {
          __schema {
              types {
                  name
                  fields {
                      name
                      type {
                          name
                      }
                  }
              }
          }
      }
      
  3. Logging:

    • Log resolvers for debugging:
      'resolve' => fn($post) => {
          Log::debug('Resolving post', ['post' => $post->toArray()]);
          return $post;
      },
      

Configuration Quirks

  1. Disable Introspection:

    • For production, disable introspection to prevent schema leaks:
      DocumentValidator::addRule(new DisableIntrospection());
      
  2. Custom Scalar Types:

    • Register custom scalars (e.g., for dates, UUIDs):
      $schema->addCustomScalarType(new DateTimeType());
      
  3. Validation Rules:

    • Add custom validation rules (e.g., for authentication):
      DocumentValidator::addRule(new class implements Rule {
          public function validate($document) {
              if (!auth()->check()) {
                  throw new Error('Unauthorized');
              }
          }
      });
      

Extension Points

  1. Custom Directives:

    • Add directives for advanced features (e.g., @auth):
      $schema->addDirective(new AuthDirective());
      
  2. Middleware:

    • Use middleware for pre/post-processing:
      $schema->addMiddleware(new class implements Middleware {
          public function resolve($next) {
              return $next();
          }
      });
      
  3. Error Handling:

    • Customize error formatting:
      $result = GraphQL::executeQuery($schema, $query, null, null, null, null, ['errorFormatter' => fn($e) => ['message' => $e->getMessage()]]);
      

Laravel-Specific Tips

  1. Route Caching:

    • Cache GraphQL routes for performance:
      Route::cache(['graphql']);
      
  2. Artisan Commands:

    • Generate GraphQL types from Eloquent models:
      php artisan make:graphql-type User
      
  3. Testing:

    • Use GraphQLTestCase for testing:
      public function testQuery()
      {
          $query = '{ user(id: 1) { name } }';
          $result = $this->graphQL($query);
          $result->assertNoErrors()->assertJson(['data' => ['user' => ['name' => 'John']]]);
      }
      
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport
twbs/bootstrap4