Skip to content

10.0.0

Latest

Choose a tag to compare

@mfn mfn released this 18 Jun 15:21
5597d9f

graphql-laravel 10.0.0

This is the stable release of the 10.x series.

Version 10 focuses on safer production defaults, cleaner core architecture, and moving the optional Eloquent query-selection machinery into its own package.

Before upgrading, read the Upgrade Guide. For the complete RC-by-RC history and pull request references, see the Changelog.

Most Important Upgrade Notes

SelectFields moved to a separate package

SelectFields is no longer part of core.

If you use SelectFields, install the new package:

composer require rebing/graphql-laravel-select-fields

For most users, this is enough. The package keeps the original namespaces and reads the same field config keys such as model, alias, selectable, always, is_relation, and query.

Core removals related to this extraction:

  • Rebing\GraphQL\Support\SelectFields removed from core
  • Closure type-hint in resolve() no longer auto-injects a SelectFields factory unless the external package is installed
  • Field::selectFieldClass() removed
  • Field::instanciateSelectFields() removed
  • Generated query/mutation stubs no longer include SelectFields boilerplate

Security defaults are stricter

Version 10 changes several defaults to be safer for production deployments:

  • Schemas now default to POST only
  • Batching is disabled by default
  • Batch size is limited by batching.max_batch_size, default 10
  • Introspection is disabled by default
  • Query depth defaults to 13
  • Query complexity defaults to 500
  • Authorization now runs before validation
  • authorize() must return exactly true

If you previously relied on open defaults, explicitly configure them during upgrade.

To re-enable introspection, for example in development:

GRAPHQL_DISABLE_INTROSPECTION=false

To re-enable GET requests:

'method' => ['GET', 'POST'],

If you enable GET, also enable ReadOnlyOperationMiddleware after AutomaticPersistedQueriesMiddleware so mutations and subscriptions are rejected on GET requests.

Privacy signatures changed

Privacy::validate() now receives the parent/root object and field arguments:

-public function validate(array $queryArgs, $queryContext = null): bool
+public function validate(mixed $root, array $fieldArgs, mixed $queryContext = null, ?ResolveInfo $resolveInfo = null): bool

Privacy closures receive the same shape:

-'privacy' => function (array $args, $ctx): bool {
+'privacy' => function (mixed $root, array $args, $ctx, ?ResolveInfo $info = null): bool {

The old first argument represented root query arguments. The new $fieldArgs contains the field's own arguments.

Middleware signatures changed

Resolver middleware now declares native mixed parameter and return types. Custom middleware overriding handle() must match:

-public function handle($root, array $args, $context, ResolveInfo $info, Closure $next)
+public function handle(mixed $root, array $args, mixed $context, ResolveInfo $info, Closure $next): mixed

authorize() signature changed

The unused $getSelectFields parameter was removed:

-public function authorize($root, array $args, $ctx, ?ResolveInfo $resolveInfo = null, ?Closure $getSelectFields = null): bool
+public function authorize($root, array $args, $ctx, ?ResolveInfo $resolveInfo = null): bool

Highlights

OpenTelemetry tracing support

Version 10 adds tracing infrastructure with an OpenTelemetry driver.

New tracing components include:

  • TracingDriver
  • TracingManager
  • TracingExecutionMiddleware
  • TracingResolverMiddleware
  • OpenTelemetryTracingDriver

Tracing is disabled by default and can be enabled globally or per schema.

CSRF protection middleware

A new opt-in HTTP middleware is available:

Rebing\GraphQL\Support\Middleware\CsrfGuard::class

Use this for GraphQL endpoints that rely on cookie/session authentication, including Laravel session auth or Sanctum cookie mode.

Read-only GET enforcement

A new opt-in execution middleware rejects mutations and subscriptions submitted through GET:

Rebing\GraphQL\Support\ExecutionMiddleware\ReadOnlyOperationMiddleware::class

This is especially relevant if you enable GET for CDN-cacheable persisted queries.

Extensible resolver parameter injection

External packages can now hook into resolver parameter injection through:

  • Rebing\GraphQL\Support\Contracts\ResolverParameterInjector
  • Field::registerParameterInjector()
  • Field::clearParameterInjectors()

This is what allows the external SelectFields package to restore SelectFields injection without keeping it in core.

Fixes And Behavior Improvements

  • APQ middleware validates queries before persisting them in cache
  • APQ cache lookup race condition fixed
  • APQ config no longer calls config() inside the config file
  • OperationParams now copies originalInput and readOnly
  • Route middleware is no longer duplicated when no per-schema middleware is defined
  • AddAuthUserContextValueMiddleware now resolves the guard from schema/global route config
  • Cross-field validation rules in nested InputTypes now work correctly
  • privacy on nested/sub-type fields is now enforced through field resolvers
  • GraphQL::type() has a narrower PHPStan return type
  • make:graphql:executionMiddleware is now registered correctly
  • Minimum webonyx/graphql-php version is now ^15.31.0

Links