Skip to content
CAI
Software that uses CAICheck a score

webonyx/graphql-php

74.9

Strong · 19 September 2026

29k

lines of production code

PHP

primary language

1

measurement over time

CAI band scale
CAI lens gauges

What this system is

This is a PHP library for implementing GraphQL servers, providing the core infrastructure to parse, validate, and execute GraphQL queries and mutations. It features a pluggable execution engine that supports asynchronous operations via adapters for AMPHP and ReactPHP, alongside a synchronous execution path. The system includes comprehensive utilities for schema construction from SDL or introspection, strict type definitions, and robust error handling with PSR-7 HTTP server integration.

How it got here

2015 — Initial project scaffolding and core architecture

16 changes.

This period established the foundational structure of the GraphQL PHP library, introducing comprehensive CI configuration, coding standards, and development tooling. It implemented the core execution engine, a spec-compliant language layer with strict typing, and a modernized type system with pluggable executors and deferred field resolution. The release also included extensive validation rules, schema building utilities, and a full test suite to ensure correctness and performance.

2016–2017 — Async execution and server integration

12 changes.

This period focused on decoupling the executor from specific async platforms by introducing generic promise adapters for React and Amp, alongside a synchronous execution path. It also established a robust HTTP handling layer via PSR-7 support in the StandardServer and significantly improved error security through client-safe formatting. The work was complemented by comprehensive benchmarking tools and extensive test coverage for these new core components.

2018–2023 — Test coverage expansion and async examples

13 changes.

This period focused on significantly expanding test coverage for core components such as error handling, executor fixtures, type validation, and AST nodes, while introducing regression tests for critical issues. It also added comprehensive examples for Schema Definition Language, standard server configuration, and asynchronous execution using AMPHP and ReactPHP. Additionally, validation rules were strengthened to prevent circular references in input objects, and PHPStan configuration was updated to support multiple PHP versions.

2025–2026 — Async execution and schema customization examples

4 changes.

This period focused on expanding the project's example suite to demonstrate advanced schema customization, including type config decorators and scalar overrides. It also introduced updated AMPHP v3 examples showcasing fiber-based asynchronous execution and modern adapter patterns for GraphQL servers.

Features

AMPHP v3 example with fiber-based async execution

Added new examples for AMPHP v3 that utilize fiber-based asynchronous execution. The event-loop example demonstrates how to use the \AmpFutureAdapter\ instead of the previous \AmpPromiseAdapter\, requiring resolvers to return \Amp\\Future\ objects via \Amp\\async\ rather than \Amp\\Promise\. The http-server example provides a complete standalone server implementation using \Amp\\Http\\Server\ that integrates with the same \AmpFutureAdapter\ for GraphQL execution.

examples/04-async-php/amphp-v3 · high confidence

Add AMPHP async examples for event-loop and HTTP server contexts

New examples demonstrating how to integrate GraphQL with AMPHP for asynchronous execution. The set includes an event-loop example that combines async capabilities with traditional request models (like Apache or FPM) for better request separation, and an HTTP server example using Amp's HttpServer to handle requests directly. Both examples utilize a shared schema where resolvers for 'product' and 'article' are implemented as non-blocking AMPHP promises, illustrating how to fetch data from microservices asynchronously.

examples/04-async-php/amphp · high confidence

Add ReactPHP async HTTP server example

A new example demonstrating how to run a GraphQL server asynchronously using ReactPHP has been added to the examples directory. This includes a README with setup instructions and a \graphql.php\ script that implements a basic HTTP server handling echo and sum operations via React's promise adapter.

examples/04-async-php/reactphp · high confidence

Add Schema Definition Language example with query and mutation support

A new example demonstrating the Schema Definition Language (SDL) has been added to the examples directory. This example shows how to define a schema using SDL and wire up resolvers as plain functions, specifically including support for both a query (echo) and a mutation (sum).

examples/02-schema-definition-language · high confidence

Add standard server example using SchemaConfig

The 03-standard-server example now demonstrates creating a GraphQL schema by explicitly using the SchemaConfig object, aligning with the library's recommended configuration pattern. The example includes a PHP script that defines query and mutation types and initializes the StandardServer, along with a README providing instructions to run the local test server and execute sample queries and mutations.

examples/03-standard-server · high confidence

Added Hello World example

A new single-file example demonstrating core GraphQL concepts including a Query with an 'echo' field and a Mutation with a 'sum' field. The example uses the SchemaConfig object to define the schema and includes instructions for running a local PHP server and testing queries via curl.

examples/00-hello-world · high confidence

Added benchmark utilities for generating GraphQL schemas and queries

Introduced two new utility classes in the benchmarks/Utils directory to support performance testing: SchemaGenerator, which programmatically constructs complex GraphQL schemas with configurable nesting levels, field counts, and argument types, and QueryGenerator, which builds GraphQL query strings targeting a specific percentage of leaf fields within a given schema. These tools provide a foundation for measuring and optimizing library performance.

benchmarks/Utils · high confidence

Example demonstrating per-schema scalar overrides

Added an example script showing how to override built-in scalar types (specifically String) with a custom trimmed-string implementation. The example illustrates two methods for applying this override within a GraphQL schema: using the 'types' configuration array and using a custom 'typeLoader' callback.

examples/06-per-schema-scalar-override · high confidence

Initial project scaffolding and CI configuration

This change introduces the foundational configuration files for the repository, including \.gitattributes\ to manage line endings and export ignores, \.gitignore\ for local artifacts, and \.codecov.yml\ to configure code coverage reporting thresholds. It also adds the coding standard configuration (\.php-cs-fixer.php\ and \.php-cs-fixer.dockerfile\), static analysis setup (\phpstan.neon.dist\ and \phpstan-baseline.neon\), testing configuration (\phpunit.xml.dist\), and automation tools (\renovate.json\ for dependency updates, \rector.php\ for code modernization, and \phpbench.json\ for performance benchmarks). Additionally, it establishes the project's documentation structure with \mkdocs.yml\, a \Makefile\ for common development tasks, and formalizes contribution and security guidelines via \CONTRIBUTING.md\, \SECURITY.md\, and \UPGRADE.md\.

(repo-wide) · high confidence

Introduce new Type subsystem classes for schema introspection and configuration

This change adds several new classes to the src/Type namespace to support schema introspection, configuration, and validation. The new Introspection class provides a static method to generate introspection queries with configurable options such as descriptions, directive repeatability, schema descriptions, specifiedByURL, and type isOneOf fields. The SchemaConfig class offers a fluent interface for configuring schema construction, including query, mutation, and subscription types, type loaders, scalar overrides, directives, and AST nodes. The Schema class manages schema types, including lazy loading and scalar overrides. The SchemaValidationContext class handles schema validation, including root types, scalar overrides, and directive definitions. The TypeKind class defines constants for type kinds.

src/Type · high confidence

Introduces generic promise support via Promise and PromiseAdapter interfaces

The library now supports generic promises through a new \Promise\ wrapper class and a \PromiseAdapter\ interface, allowing integration with various async PHP platforms (such as ReactPHP or AMPHP) without hardcoding specific promise types. The \Promise\ class acts as a convenience wrapper that delegates operations like \then()\ to the configured adapter, while the \PromiseAdapter\ interface defines the contract for converting thenables, creating fulfilled/rejected promises, and handling promise aggregation via \all()\. This change enables users to plug in their preferred promise library by implementing the adapter, making the executor's async behavior platform-agnostic.

src/Executor/Promise · high confidence

New StandardServer and Helper classes for PSR-7 and HTTP request handling

The src/Server location introduces a new StandardServer class and a Helper utility class to handle GraphQL execution. StandardServer provides a unified entry point that supports both traditional PHP globals-based HTTP requests and PSR-7 ServerRequestInterface objects via the new executePsrRequest and processPsrRequest methods. The Helper class implements the underlying logic for parsing HTTP requests (including JSON, form-urlencoded, and multipart/form-data bodies), validating operation parameters, and executing operations or batches. This change also introduces a set of specific exception classes in src/Server/Exception (such as CannotParseJsonBody, BatchedQueriesAreNotSupported, and InvalidQueryParameter) to replace generic errors with more descriptive types, and adds support for Apollo server/client compatibility by allowing query IDs to be derived from extensions.

src/Server · high confidence

New blog example with typed data models and lazy type registry

The blog example now uses strongly-typed PHP data classes (User, Story, Comment, Image) for its in-memory data layer, replacing previous array-based structures. It introduces a TypeRegistry to lazily resolve GraphQL types, preventing circular dependency issues during schema construction. The example also demonstrates custom scalar types (Email, URL), a reusable HtmlField builder for content formatting, and an Interface/Union pattern (Node, SearchResult) to model polymorphic relationships.

examples/01-blog/Blog · high confidence

New example demonstrating type config decorators with SDL

Added a new example in \examples/05-type-config-decorator\ that shows how to resolve object types in a GraphQL query using the Schema Definition Language (SDL) combined with a \typeConfigDecorator\. The example implements a simple API server that fetches data from a remote REST endpoint, defining the schema in \schema.graphql\ and using the decorator to inject custom resolve logic for the \Query.tracksForHome\ and \Track.author\ fields.

examples/05-type-config-decorator · high confidence

New promise adapters for Amp and React, plus a synchronous execution path

The Executor now supports additional promise libraries and synchronous execution. New adapters have been added for Amp (both \AmpFutureAdapter\ for AMPHP v3 fiber-based futures and \AmpPromiseAdapter\ for standard Amp promises) and React-Promise (\ReactPromiseAdapter\), allowing GraphQL execution to integrate with these async runtimes. Additionally, a new synchronous execution path is provided via \SyncPromise\ and \SyncPromiseAdapter\, which use a dedicated \SyncPromiseQueue\ to process deferred tasks in-memory, enabling deterministic, non-async GraphQL resolution without external promise libraries.

src/Executor/Promise/Adapter · high confidence

New schema building and introspection utilities

The \src/Utils\ directory now includes new classes to support building GraphQL schemas from SDL and introspection results. \BuildSchema\ allows constructing a schema from a string or AST, while \BuildClientSchema\ builds a schema from an introspection query result for use by client tools. \SchemaExtender\ enables extending an existing schema with additional SDL definitions. Additionally, \AST\ provides utilities for converting between PHP arrays and AST nodes, and \BreakingChangesFinder\ helps identify breaking changes between two schemas.

src/Utils · high confidence

New validation rules for OneOf input objects and disabling introspection

The validator now includes a \OneOfInputObjectsRule\ that enforces the GraphQL \@oneOf\ directive, requiring exactly one non-null field to be provided for OneOf input types. Additionally, a \DisableIntrospection\ rule has been added to allow disabling GraphQL introspection queries (\\_\schema\ and \\\_type\), returning an error if they are detected when the feature is disabled.

src/Validator/Rules · high confidence

Validation engine now supports SDL schema definitions alongside queries

The validator has been extended to validate GraphQL Schema Definition Language (SDL) documents, not just query documents. This is achieved by introducing a new \SDLValidationContext\ class and a dedicated set of validation rules (accessible via \DocumentValidator::sdlRules()\) that check schema structure, such as unique type and directive names. The main \DocumentValidator\ now distinguishes between query validation (using \QueryValidationContext\) and schema validation, allowing users to validate their schema definitions for correctness during the build process.

src/Validator · high confidence

Behavioural changes

AST nodes restructured with strict typing and NodeList collections

The AST node classes in src/Language/AST have been completely rewritten to use strict PHP types and a dedicated NodeList class for collections. Every node now explicitly defines its kind, required properties, and optional fields (like descriptions and directives) using strong typing, replacing previous loose array-based structures. The new NodeList class handles lazy conversion of raw arrays to AST nodes and provides methods for manipulation, improving type safety and performance for schema parsing and validation.

src/Language/AST · high confidence

Complete rewrite of the GraphQL language layer (lexer, parser, printer, and visitor)

The \src/Language\ directory has been replaced with a new, spec-compliant implementation of the GraphQL language tools. This includes a new O(N) Lexer that handles UTF-8 and block strings, a Parser supporting the April 2016 spec with partial parsing capabilities and recursion limits, a Printer for AST serialization, and a Visitor for AST traversal. The change introduces new classes such as \BlockString\, \DirectiveLocation\, \Source\, \Token\, and \VisitorOperation\, and updates the AST node handling to use \NodeList\ and \NodeKind\ for better type safety and performance.

src/Language · high confidence

Executor refactored into pluggable implementation with scoped context support

The execution engine has been restructured to support pluggable executor implementations via a new \ExecutorImplementation\ interface and factory pattern, allowing for alternative execution strategies (such as coroutine-based executors) while retaining the \ReferenceExecutor\ as the default. A new \ExecutionContext\ class now centralizes execution state (schema, fragments, variables, and errors), and the \ExecutionResult\ class has been enhanced to support custom error formatters, error handlers, and user-defined extensions. Additionally, a new \ScopedContext\ interface allows context values to be cloned per field, enabling isolated state updates for child fields without affecting siblings.

src/Executor · high confidence

New Deferred class and refactored GraphQL facade for deferred execution

The library introduces a new \Deferred\ class in \src/Deferred.php\ that extends \SyncPromise\ to handle deferred field resolution by enqueuing an executor callback, providing a user-facing promise mechanism for lazy loading. Concurrently, the \src/GraphQL.php\ facade has been refactored to expose \executeQuery\ and \promiseToExecute\ methods, replacing previous static execution patterns; \executeQuery\ now synchronously waits on a promise using \SyncPromiseAdapter\, while \promiseToExecute\ allows integration with async platforms by accepting a custom \PromiseAdapter\. The facade also enforces query complexity validation by setting raw variable values on the \QueryComplexity\ rule before execution and deprecates \getStandardDirectives\ in favor of \Directive::builtInDirectives()\.

src · high confidence

PHPStan configuration now adapts to the runtime PHP version

The static analysis setup has been reworked to automatically select configuration rules based on the PHP version in use. A new entry script loads specific PHPStan configuration files (e.g., for PHP 8.2+, below 8.2, below 8.1, or below 8.0) to handle version-specific issues such as enum support, property access changes, and type narrowing behaviors. This ensures that static analysis remains accurate across different PHP environments without requiring manual configuration overrides.

phpstan · high confidence

Refactored error handling with client-safe formatting and debug flags

The error handling system has been restructured to improve security and debugging capabilities. A new \ClientAware\ interface allows errors to declare whether their messages are safe to display to end-users; by default, the error formatter now replaces non-client-safe messages with "Internal server error" to prevent information leakage. A new \DebugFlag\ class provides granular control over debug output, including flags to include debug messages, stack traces, and rethrow internal or unsafe exceptions. Additionally, a new \CoercionError\ class preserves the invalid input value and path for better diagnostics, and a \Warning\ system has been introduced to allow suppression and custom handling of library warnings.

src/Error · high confidence

Refactored type definitions into a modern, interface-driven architecture

The type definition system has been restructured to use a composition of interfaces (such as AbstractType, CompositeType, InputType, and HasFieldsType) and traits (HasFieldsTypeImplementation, ImplementingTypeImplementation) instead of relying solely on class inheritance. This change introduces a new AbstractType interface that enforces a specific execution order for abstract types: resolveValue is now called before resolveType, allowing resolvers to transform the object value before its concrete type is determined. Additionally, the refactoring brings stricter validation for field visibility, argument types, and input object fields, while preserving backward compatibility for existing schema definitions.

src/Type/Definition · high confidence

Simplified blog example with updated schema configuration

The blog example has been refactored to use the new \SchemaConfig\ object for schema construction instead of the previous constructor arguments, and the entry point script has been renamed from \index.php\ to \graphql.php\ for consistency. The example now initializes a fake data source and sets up a standard server with an application context containing the currently logged-in user, providing a clearer starting point for newcomers to understand schema definition and query execution.

examples/01-blog · high confidence

Validation of non-nullable circular references in Input Objects

The library now detects and reports errors when an Input Object type contains a circular reference chain involving non-nullable fields. This new validation rule prevents schema definitions that would lead to unbreakable cycles during execution, ensuring that input structures are acyclic where non-null constraints apply.

src/Type/Validation · high confidence

Test coverage

Added PHPBench performance benchmarks for core GraphQL operations; Added PHPStan type-specifying extensions for GraphQL type checks; Added Star Wars end-to-end test suite and supporting test utilities; Added comprehensive test coverage for GraphQL Type system definitions; Added comprehensive test coverage for GraphQL Utils; Added comprehensive test coverage for the GraphQL Language layer; Added comprehensive test suite for GraphQL Executor; Added comprehensive test suite for the GraphQL Server component; Added regression tests for union/interface resolveType paths and input object validation; Added test coverage for GraphQL Error handling and formatting; Added test coverage for GraphQL validation rules; Added test coverage for Promise adapters; Added test fixture classes for executor scenarios; Added test fixtures for PHP Enum type handling; Added test fixtures for custom GraphQL type implementations; Added tests for AST Node cloning, JSON serialization, and string conversion; Added tests for Type definition utilities.

Dependencies

Initial release of GraphQL PHP library with comprehensive dev tooling

The project introduces its first official release (v0.1), establishing the core \webonyx/graphql-php\ library with support for PHP 7.4 and 8.x. The distribution includes a robust development environment featuring PHPStan 2.2.8 with strict rules and PHPUnit extensions, PHP CS Fixer 3.95.25 for code styling, Rector 2.0 for refactoring, and PHPBench 1.2 for performance benchmarking. The library also provides examples and suggests integrations with async platforms like AmpHP and ReactPHP, alongside PSR-7 HTTP message support.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Baseline

  • First survey — no prior run to compare against. CAI 75.

Lenses

  • Code Health 85
  • Architecture 92
  • Maturity 69
  • Readiness 74
  • Security 85

Changes since last survey

  • 300 commits — 263 feature/other, 37 fixes

By area

  • (root) — 177 commits
  • (repo) — 17 commits
  • src/Type — 14 commits
  • .github/workflows — 13 commits
  • src/Utils — 9 commits
  • tests/Executor — 9 commits
  • examples/04-async-php — 8 commits
  • src/Language — 8 commits
  • tests/Utils — 8 commits
  • src/Executor — 5 commits
  • src/Validator — 5 commits
  • tests/Validator — 5 commits
  • .ai/AGENTS.md — 4 commits
  • docs/type-definitions — 3 commits
  • benchmarks/LexerBench.php — 2 commits
  • docs/class-reference.md — 2 commits
  • phpstan/php-below-8.2.neon — 2 commits
  • tests/Type — 2 commits
  • .claude/settings.json — 1 commit
  • .github/FUNDING.yml — 1 commit

Notable commits

  • fix: Add CHANGELOG entry for SingleFieldSubscription fix
  • fix: Address review comments: introspection specifiedByURL, custom directive override safety, multi-directive exclusion fix
  • fix: Apply latest rector fixes (#1777)
  • fix: Apply latest rector fixes and update its configuration
  • fix: Apply latest rector fixes to tests
  • fix: Fix "Cannot traverse an already closed generator" in Schema::getTypeMap()
  • fix: Fix @see annotations to match graphql-js test names exactly
  • fix: Fix PHP 7.4 compatibility broken by \Stringable interface (#1810)
  • fix: Fix SingleFieldSubscription to expand fragments and reject introspection/@skip/@include
  • fix: Fix code style issues found by autofix.ci: import ordering and docblock formatting
  • fix: Fix directive ordering and trailing newline in test heredoc
  • fix: Fix directive ordering in BuildSchema.php: append oneOf before specifiedBy
  • fix: Fix directiveExcludesField and tighten getSpecifiedByURL parameter type
  • fix: Fix loose switch comparison mistaking NUL byte for EOF in string escapes
  • fix: Fix package name
  • fix: Fix parseLiteral not called on per-schema scalar overrides for inline arguments (#1880)
  • fix: Fix php-cs-fixer
  • fix: Fix php-cs-fixer Docker build for older PHP versions
  • fix: Fix query complexity for fragments defined after operations
  • fix: Fix scalar overrides not applied without assertValid() (#1886)
  • …and 280 more

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

webonyx/graphql-php was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 19 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit f18cd3172e72544c8fc4dc0c8de8524cc259029f — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-13a154b7f5d1.