webonyx/graphql-php

repository·master·Indexed 26 days ago

https://github.com/webonyx/graphql-php

A PHP implementation of the GraphQL specification, designed to be compliant with the official spec and based on the JavaScript reference implementation. It provides tools for executing queries via executeQuery() and promiseToExecute(), managing schemas with SchemaConfig, and defining types using the GraphQL\Type\Definition\Type class. The library follows Semantic Versioning 2.0.0 and provides a public API marked with @api tags for stability.

Tokens
36.7K
Snippets
87
Records
178
Agent score
89%

What's inside graphql-php

  1. Overview of graphql-php features

    master

    graphql-php is a feature-complete implementation of the GraphQL specification in PHP. It acts as a thin wrapper around your existing data layer and business logic without dictating implementation details.

    Key features include:

    • Primitives to express your application as a Type System.
    • Validation and introspection of the Type System (compatible with tools like GraphiQL).
    • Parsing, validating, and executing GraphQL queries.
    • Rich error reporting for both query validation and execution errors.
    • Optional tools for parsing Schema Definition Language (SDL).
    • Tools for batching requests to backend storage (solving the N+1 problem).
    • Support for Async PHP platforms via promises.
    • Standard HTTP server support.
  2. Understand GraphQL error types

    master

    GraphQL errors fall into three categories:

    1. Syntax: The query has invalid syntax and cannot be parsed. An exception is thrown and execution stops.
    2. Validation: The query is incompatible with the type system (e.g., requesting an unknown field). An exception is thrown and execution stops.
    3. Execution: Occurs when a field resolver throws an exception or returns an unexpected value. These are caught and collected in the $errors property of the GraphQL\Executor\ExecutionResult.

    Error Bubbling Behavior:

    • If a resolver for a nullable field fails, the field value is replaced with null and an error is registered.
    • If a resolver for a non-null field fails, the error bubbles up to the first nullable parent. That parent is replaced with null.
    • If all fields up to the root are non-null, the data key is removed from the response, leaving only the errors key.
  3. Enhance graphql-php with server utilities

    master

    Several utilities can extend the functionality of graphql-php for specific tasks:

    Schema Definition

    • Annotations/Attributes:
    • Builders:
      • GraphQL Utils: Objective schema definition builders to avoid array-based configuration.
      • Relay Library: Helps construct Relay-related schema definitions.

    Data Fetching & ORM

    • Doctrine ORM:
    • Performance & Batching:
      • DataLoaderPHP: Implements deferred resolvers to solve the N+1 problem.
      • GraphQL Batch Processor: Builder interface for defining collection, querying, filtering, and post-processing logic for batched data fetches.

    Specialized Features

  4. Understand GraphQL type categories in graphql-php

    master

    In graphql-php, types are categorized into Input and Output types. This distinction determines whether a type can be used as a field in a response or as an argument in a query.

    • Output types (field types): ScalarType, EnumType, ObjectType, InterfaceType, and UnionType.
    • Input types (argument types): ScalarType, EnumType, and InputObjectType.

    Note that NonNull and List wrappers can belong to either category depending on the type they wrap.

  5. Integrate graphql-php with various web servers

    master

    You can use graphql-php with several server-side integrations depending on your framework or architecture:

    • PSR-7 Frameworks: Use the Standard Server approach for out-of-the-box integration with any PSR-7 compatible framework (e.g., Slim or Laminas Mezzio).
    • Laravel:
    • Symfony: OverblogGraphQLBundle.
    • WordPress: WP-GraphQL plugin.
    • Swoole/High Performance: Siler (supports flat files and plain PHP functions).
    • Model-Driven: API Platform (creates GraphQL APIs directly from PHP models).
  6. Use GraphQL clients for testing and development

    master

    To interact with your graphql-php server, you can use the following clients:

    Interactive IDEs (Browser-based)

    • GraphiQL: Graphical interactive in-browser GraphQL IDE.
    • GraphQL Playground: IDE for enhanced workflows including GraphQL Subscriptions, interactive docs, and collaboration.

    Desktop & Specialized Clients

  7. Understand core GraphQL concepts: Schema, Query, and Mutation

    master

    GraphQL is a data-centric language built around three major pillars:

    1. Schema (Type System): The definition of your application's data structure and capabilities.
    2. Query: A request for structured data. Queries are designed to mirror the shape of the expected JSON response and are intended to be idempotent.
    3. Mutation: A request to perform side effects (creating, updating, or deleting data). Unlike Query fields, fields within the root Mutation type are executed serially.

    Typically, you expose your Schema via a single HTTP endpoint where clients send Queries and Mutations (usually via HTTP POST).

  8. Define GraphQL descriptions in v0.12.x

    master

    In v0.12.x, comments are no longer used as descriptions by default. Descriptions must now be defined using Strings or BlockStrings within the GraphQL language. If you need to maintain the old behavior, you can provide the commentDescriptions option to BuildSchema::buildAST(), BuildSchema::build(), or Printer::doPrint().

    New way to define descriptions:

    "Description"
    type Dog {
      ...
    }
    
    """
    Long Description
    """
    type Dog {
      ...
    }
    "Description"
    type Dog {
      ...
    }
    
    """
    Long Description
    """
    type Dog {
      ...
    }
  9. Migrate from v14.x.x to v15.x.x: Error Handling and Server Changes

    master

    When upgrading to v15.x.x, note the following breaking changes:

    Removed error extension field category

    Errors implementing ClientAware no longer include the category key in their formatted output. The ClientAware::getCategory() method has been removed. If you need to maintain the old format, implement custom error formatting.

    StandardServer execution changes

    The $exitWhenDone argument has been removed from StandardServer::send500Error() and StandardServer::handleRequest(). If your application logic requires the process to exit after handling a request, you must call exit manually.

    $server = new GraphQL\Server\StandardServer();
    -$server->handleRequest($body, true);
    +$server->handleRequest($body);
    +exit;
  10. Execute Queries Asynchronously with Promises

    master

    If your environment supports async operations (ReactPHP, AMPHP, Swoole, etc.), you can resolve fields asynchronously using Promises.

    1. Use GraphQL::promiseToExecute instead of executeQuery.
    2. Provide a $promiseAdapter compatible with your runtime.
    3. Ensure your resolve functions return platform-specific Promises instead of GraphQL\Deferred objects.

    Supported Adapters:

    • ReactPHP: GraphQL\Executor\Promise\Adapter\ReactPromiseAdapter (requires react/promise)
    • AMPHP: GraphQL\Executor\Promise\Adapter\AmpPromiseAdapter
    • Swoole/OpenSwoole: Use an external library like Resonance
    • Custom: Implement GraphQL\Executor\Promise\PromiseAdapter
    use GraphQL\GraphQL;
    use GraphQL\Executor\ExecutionResult;
    
    $promise = GraphQL::promiseToExecute(
        $promiseAdapter,
        $schema,
        $queryString,
        $rootValue = null,
        $contextValue = null,
        $variableValues = null,
        $operationName = null,
        $fieldResolver = null,
        $validationRules = null
    );
    
    $promise->then(fn (ExecutionResult $result): array => $result->toArray());
  11. Install GraphiQL for API exploration

    master

    For a more convenient way to explore your GraphQL APIs with syntax highlighting and auto-completion, you can use GraphiQL. The easiest way is to install a Google Chrome extension:

    • ChromeiQL
    • GraphiQL Feen

    Alternatively, you can install GraphiQL locally following the official GraphiQL instructions.

  12. Handle Schema Invariant Violations

    master

    Errors in type definitions (e.g., logical errors in your schema) throw GraphQL\Error\InvariantViolation. These should typically be treated as server errors (HTTP 500).

    When building a schema, wrap the instantiation in a try-catch block to capture these errors and return a proper JSON error response.

    use GraphQL\GraphQL;
    use GraphQL\Type\Schema;
    use GraphQL\Error\FormattedError;
    
    try {
        $schema = new Schema([
            // ...
        ]);
    
        $body = GraphQL::executeQuery($schema, $query);
        $status = 200;
    } catch(\Exception $e) {
        $body = [
            'errors' => [
                FormattedError::createFromException($e)
            ]
        ];
        $status = 500;
    }
    
    header('Content-Type: application/json', true, $status);
    echo json_encode($body, JSON_THROW_ON_ERROR);