Skip to content

Commit 2400ae8

Browse files
committed
Introduce scope-aware Context and #[MapContext]
Resolvers often need per-request data that is neither a GraphQL input nor a DI service: the current HTTP request, the authenticated user, or a value computed by an ancestor field. Until now the generated resolver closures ignored webonyx's context value entirely, so the only escape hatches were `#[Arg]` (client input) and `#[Autowire]` (container), and there was no way to thread request state to a resolver. This adds a first-class `Context` value object and a `#[MapContext]` parameter attribute. `Context` is a webonyx `ScopedContext` that stores objects by class (`attachObject`/`getObject`/`maybeGetObject`) and also implements `ArrayAccess`; because it is scoped, a value attached by a resolver is visible to its descendants without leaking to siblings. `#[MapContext]` injects an object from the `Context` into a resolver parameter by its type — nullable parameters resolve to `null` when absent, non-nullable parameters throw. The generated query, mutation, and field closures now receive webonyx's context as a `mixed` value and pass it through to `ArgumentNodeResolver`. The value is left untouched (it can be anything the server provides); only `#[MapContext]` resolution requires it to be a `Context`, throwing a `ContextException` otherwise. Wiring a `Context` onto the server is up to the consumer via the webonyx `context` option (see the docs).
1 parent c35d166 commit 2400ae8

34 files changed

Lines changed: 929 additions & 17 deletions

docs/getting_started.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ $server = new StandardServer(ServerConfig::create([
4545
]));
4646
```
4747

48+
💡 *Want to pass per-request data (the HTTP request, the current user, …) to your resolvers? Set a*
49+
`Context` *as the server's context value and read it with* `#[MapContext]`*. See*
50+
[#[MapContext]](usage.md#mapcontext) *and* [Context](usage.md#context).
51+
4852
📌 *This library does not create a GraphQL server for you.*
4953

5054
To learn how to set up a server, check the [webonyx documentation](https://webonyx.github.io/graphql-php/executing-queries/#using-server).

docs/usage.md

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ You can use the following attributes:
2121
- [#[Field]](#field)
2222
- [#[Arg]](#arg)
2323
- [#[Autowire]](#autowire)
24+
- [#[MapContext]](#mapcontext)
2425
- [#[Scalar]](#scalar)
2526
- [#[Cursor]](#cursor)
2627

@@ -492,6 +493,107 @@ By default, the service to inject is determined by the parameter type. If needed
492493
|-----------|------------------------------------------------------------------------------------|
493494
| `service` | *(Optional)* Custom service identifier to retrieve from the DI container (PSR-11). |
494495

496+
### #[MapContext]
497+
498+
Webonyx/graphql-php passes a **context value** to every resolver. This library wraps it in a
499+
`Context` object (see [Context](#context)) that you can populate per request — for example with the
500+
current HTTP request, the authenticated user, or any value resolved higher up in the query tree.
501+
502+
`#[MapContext]` injects an object stored in that `Context` into a resolver parameter, looked up by the
503+
parameter's type. It works on `#[Query]`, `#[Mutation]`, and `#[Field]` method parameters.
504+
505+
```php
506+
use Jerowork\GraphqlAttributeSchema\Attribute\MapContext;
507+
use Jerowork\GraphqlAttributeSchema\Attribute\Query;
508+
use Symfony\Component\HttpFoundation\Request;
509+
510+
final readonly class YourQuery
511+
{
512+
#[Query]
513+
public function yourQuery(
514+
int $filter,
515+
#[MapContext]
516+
Request $request,
517+
): YourType {
518+
// $request is fetched from the Context by its class
519+
}
520+
}
521+
```
522+
523+
A resolver can also attach objects to the `Context` so descendant fields can read them through
524+
`#[MapContext]`. Because `Context` is a webonyx `ScopedContext`, children receive a clone, so values
525+
attached by a resolver are visible to its descendants without leaking to sibling fields:
526+
527+
```php
528+
#[Field]
529+
public function getChild(Context $context): ChildType
530+
{
531+
$context->attachObject(new Locale('en'));
532+
// ... children resolving under this field can now `#[MapContext] Locale $locale`
533+
}
534+
```
535+
536+
#### Nullable parameters
537+
538+
- A **non-nullable** parameter (`Request $request`) throws a `ContextException` when no matching object
539+
is present in the `Context`.
540+
- A **nullable** parameter (`?Request $request`) resolves to `null` when no matching object is present.
541+
542+
#### Requirements
543+
544+
- The parameter must be type-hinted with a class (not a built-in type).
545+
- The GraphQL context value **must** be an instance of
546+
`Jerowork\GraphqlAttributeSchema\Context`. If it is anything else, a `ContextException` is thrown when
547+
the parameter is resolved. See [Context](#context) for how to set this up on your server.
548+
549+
### Context
550+
551+
`Jerowork\GraphqlAttributeSchema\Context` is the per-request context value passed to your resolvers. It
552+
stores objects keyed by their class and also implements `ArrayAccess`, so you can use it as a typed
553+
container or as a simple map.
554+
555+
```php
556+
use Jerowork\GraphqlAttributeSchema\Context;
557+
558+
$context = new Context();
559+
560+
// Attach by class
561+
$context->attachObject($request); // stored under Request::class
562+
$request = $context->getObject(Request::class); // throws if missing/wrong type
563+
$request = $context->maybeGetObject(Request::class); // null if missing
564+
565+
// Or as an array (any key)
566+
$context[Request::class] = $request;
567+
$locale = $context['locale'] ?? null;
568+
```
569+
570+
Set it on your server through the webonyx `context` option. Using a callable means a fresh `Context`
571+
is built per request:
572+
573+
```php
574+
use GraphQL\Error\DebugFlag;
575+
use GraphQL\Server\ServerConfig;
576+
use GraphQL\Server\StandardServer;
577+
use Jerowork\GraphqlAttributeSchema\Context;
578+
use Symfony\Component\HttpFoundation\Request;
579+
580+
$config = [
581+
'schema' => $this->createSchema(),
582+
'context' => function () {
583+
$context = new Context();
584+
$context[Request::class] = $this->requestStack->getMainRequest();
585+
586+
return $context;
587+
},
588+
];
589+
590+
if ($this->environment !== EnvironmentName::PROD) {
591+
$config['debugFlag'] = DebugFlag::INCLUDE_DEBUG_MESSAGE | DebugFlag::INCLUDE_TRACE | DebugFlag::RETHROW_INTERNAL_EXCEPTIONS;
592+
}
593+
594+
return new StandardServer(ServerConfig::create($config));
595+
```
596+
495597
### #[Scalar]
496598

497599
Webonyx/graphql-php comes with four built-in scalar types:

phpstan-baseline.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
'path' => __DIR__ . '/src/Node/Child/ArgNode.php',
99
];
1010
$ignoreErrors[] = [
11-
'message' => '#^Method Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\Child\\\\FieldNode\\:\\:toArray\\(\\) should return array\\{reference\\: array\\{type\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\TypeReference\\\\TypeReference\\>, payload\\: array\\<string, mixed\\>\\}, name\\: string, description\\: string\\|null, argumentNodes\\: list\\<array\\{node\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\Child\\\\ArgumentNode\\>, payload\\: array\\{reference\\: array\\{type\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\TypeReference\\\\TypeReference\\>, payload\\: array\\<string, mixed\\>\\}, name\\: string, description\\: string\\|null, propertyName\\: string\\}\\|array\\{service\\?\\: string, propertyName\\: string\\}\\}\\>, fieldType\\: string, methodName\\: string\\|null, propertyName\\: string\\|null, deprecationReason\\: string\\|null, \\.\\.\\.\\} but returns array\\{reference\\: array\\{type\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\TypeReference\\\\TypeReference\\>&literal\\-string, payload\\: array\\<string, mixed\\>\\}, name\\: string, description\\: string\\|null, argumentNodes\\: list\\<array\\{node\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\Child\\\\ArgumentNode\\>&literal\\-string, payload\\: array\\<string, mixed\\>\\}\\>, fieldType\\: \'method\'\\|\'property\', methodName\\: string\\|null, propertyName\\: string\\|null, deprecationReason\\: string\\|null, \\.\\.\\.\\}\\.$#',
11+
'message' => '#^Method Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\Child\\\\FieldNode\\:\\:toArray\\(\\) should return array\\{reference\\: array\\{type\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\TypeReference\\\\TypeReference\\>, payload\\: array\\<string, mixed\\>\\}, name\\: string, description\\: string\\|null, argumentNodes\\: list\\<array\\{node\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\Child\\\\ArgumentNode\\>, payload\\: array\\{className\\: class\\-string, propertyName\\: string, nullable\\: bool\\}\\|array\\{reference\\: array\\{type\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\TypeReference\\\\TypeReference\\>, payload\\: array\\<string, mixed\\>\\}, name\\: string, description\\: string\\|null, propertyName\\: string\\}\\|array\\{service\\?\\: string, propertyName\\: string\\}\\}\\>, fieldType\\: string, methodName\\: string\\|null, propertyName\\: string\\|null, deprecationReason\\: string\\|null, \\.\\.\\.\\} but returns array\\{reference\\: array\\{type\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\TypeReference\\\\TypeReference\\>&literal\\-string, payload\\: array\\<string, mixed\\>\\}, name\\: string, description\\: string\\|null, argumentNodes\\: list\\<array\\{node\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\Child\\\\ArgumentNode\\>&literal\\-string, payload\\: array\\<string, mixed\\>\\}\\>, fieldType\\: \'method\'\\|\'property\', methodName\\: string\\|null, propertyName\\: string\\|null, deprecationReason\\: string\\|null, \\.\\.\\.\\}\\.$#',
1212
'identifier' => 'return.type',
1313
'count' => 1,
1414
'path' => __DIR__ . '/src/Node/Child/FieldNode.php',
@@ -20,7 +20,7 @@
2020
'path' => __DIR__ . '/src/Node/Child/FieldNode.php',
2121
];
2222
$ignoreErrors[] = [
23-
'message' => '#^Method Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\MutationNode\\:\\:toArray\\(\\) should return array\\{className\\: class\\-string, name\\: string, description\\: string\\|null, argumentNodes\\: list\\<array\\{node\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\Child\\\\ArgumentNode\\>, payload\\: array\\{propertyName\\: string\\}\\|array\\{reference\\: array\\{type\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\TypeReference\\\\TypeReference\\>, payload\\: array\\<string, mixed\\>\\}, name\\: string, description\\: string\\|null, propertyName\\: string\\}\\}\\>, outputReference\\: array\\{type\\: class\\-string, payload\\: array\\<string, mixed\\>\\}, methodName\\: string, deprecationReason\\: string\\|null, deferredTypeLoader\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Type\\\\Loader\\\\DeferredTypeLoader\\>\\|null\\} but returns array\\{className\\: class\\-string, name\\: string, description\\: string\\|null, argumentNodes\\: list\\<array\\{node\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\Child\\\\ArgumentNode\\>&literal\\-string, payload\\: array\\<string, mixed\\>\\}\\>, outputReference\\: array\\{type\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\TypeReference\\\\TypeReference\\>&literal\\-string, payload\\: array\\<string, mixed\\>\\}, methodName\\: string, deprecationReason\\: string\\|null, deferredTypeLoader\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Type\\\\Loader\\\\DeferredTypeLoader\\>\\|null\\}\\.$#',
23+
'message' => '#^Method Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\MutationNode\\:\\:toArray\\(\\) should return array\\{className\\: class\\-string, name\\: string, description\\: string\\|null, argumentNodes\\: list\\<array\\{node\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\Child\\\\ArgumentNode\\>, payload\\: array\\{className\\: class\\-string, propertyName\\: string, nullable\\: bool\\}\\|array\\{reference\\: array\\{type\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\TypeReference\\\\TypeReference\\>, payload\\: array\\<string, mixed\\>\\}, name\\: string, description\\: string\\|null, propertyName\\: string\\}\\|array\\{service\\?\\: string, propertyName\\: string\\}\\}\\>, outputReference\\: array\\{type\\: class\\-string, payload\\: array\\<string, mixed\\>\\}, methodName\\: string, deprecationReason\\: string\\|null, deferredTypeLoader\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Type\\\\Loader\\\\DeferredTypeLoader\\>\\|null\\} but returns array\\{className\\: class\\-string, name\\: string, description\\: string\\|null, argumentNodes\\: list\\<array\\{node\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\Child\\\\ArgumentNode\\>&literal\\-string, payload\\: array\\<string, mixed\\>\\}\\>, outputReference\\: array\\{type\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\TypeReference\\\\TypeReference\\>&literal\\-string, payload\\: array\\<string, mixed\\>\\}, methodName\\: string, deprecationReason\\: string\\|null, deferredTypeLoader\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Type\\\\Loader\\\\DeferredTypeLoader\\>\\|null\\}\\.$#',
2424
'identifier' => 'return.type',
2525
'count' => 1,
2626
'path' => __DIR__ . '/src/Node/MutationNode.php',
@@ -32,7 +32,7 @@
3232
'path' => __DIR__ . '/src/Node/MutationNode.php',
3333
];
3434
$ignoreErrors[] = [
35-
'message' => '#^Method Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\QueryNode\\:\\:toArray\\(\\) should return array\\{className\\: class\\-string, name\\: string, description\\: string\\|null, argumentNodes\\: list\\<array\\{node\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\Child\\\\ArgumentNode\\>, payload\\: array\\{propertyName\\: string\\}\\|array\\{reference\\: array\\{type\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\TypeReference\\\\TypeReference\\>, payload\\: array\\<string, mixed\\>\\}, name\\: string, description\\: string\\|null, propertyName\\: string\\}\\}\\>, outputReference\\: array\\{type\\: class\\-string, payload\\: array\\<string, mixed\\>\\}, methodName\\: string, deprecationReason\\: string\\|null, deferredTypeLoader\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Type\\\\Loader\\\\DeferredTypeLoader\\>\\|null\\} but returns array\\{className\\: class\\-string, name\\: string, description\\: string\\|null, argumentNodes\\: list\\<array\\{node\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\Child\\\\ArgumentNode\\>&literal\\-string, payload\\: array\\<string, mixed\\>\\}\\>, outputReference\\: array\\{type\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\TypeReference\\\\TypeReference\\>&literal\\-string, payload\\: array\\<string, mixed\\>\\}, methodName\\: string, deprecationReason\\: string\\|null, deferredTypeLoader\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Type\\\\Loader\\\\DeferredTypeLoader\\>\\|null\\}\\.$#',
35+
'message' => '#^Method Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\QueryNode\\:\\:toArray\\(\\) should return array\\{className\\: class\\-string, name\\: string, description\\: string\\|null, argumentNodes\\: list\\<array\\{node\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\Child\\\\ArgumentNode\\>, payload\\: array\\{className\\: class\\-string, propertyName\\: string, nullable\\: bool\\}\\|array\\{reference\\: array\\{type\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\TypeReference\\\\TypeReference\\>, payload\\: array\\<string, mixed\\>\\}, name\\: string, description\\: string\\|null, propertyName\\: string\\}\\|array\\{service\\?\\: string, propertyName\\: string\\}\\}\\>, outputReference\\: array\\{type\\: class\\-string, payload\\: array\\<string, mixed\\>\\}, methodName\\: string, deprecationReason\\: string\\|null, deferredTypeLoader\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Type\\\\Loader\\\\DeferredTypeLoader\\>\\|null\\} but returns array\\{className\\: class\\-string, name\\: string, description\\: string\\|null, argumentNodes\\: list\\<array\\{node\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\Child\\\\ArgumentNode\\>&literal\\-string, payload\\: array\\<string, mixed\\>\\}\\>, outputReference\\: array\\{type\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Node\\\\TypeReference\\\\TypeReference\\>&literal\\-string, payload\\: array\\<string, mixed\\>\\}, methodName\\: string, deprecationReason\\: string\\|null, deferredTypeLoader\\: class\\-string\\<Jerowork\\\\GraphqlAttributeSchema\\\\Type\\\\Loader\\\\DeferredTypeLoader\\>\\|null\\}\\.$#',
3636
'identifier' => 'return.type',
3737
'count' => 1,
3838
'path' => __DIR__ . '/src/Node/QueryNode.php',
@@ -97,6 +97,12 @@
9797
'count' => 1,
9898
'path' => __DIR__ . '/src/NodeParser/Child/CursorNodeParser.php',
9999
];
100+
$ignoreErrors[] = [
101+
'message' => '#^Method Jerowork\\\\GraphqlAttributeSchema\\\\NodeParser\\\\Child\\\\MapContextNodeParser\\:\\:getAttribute\\(\\) has parameter \\$reflector with generic class ReflectionClass but does not specify its types\\: T$#',
102+
'identifier' => 'missingType.generics',
103+
'count' => 1,
104+
'path' => __DIR__ . '/src/NodeParser/Child/MapContextNodeParser.php',
105+
];
100106
$ignoreErrors[] = [
101107
'message' => '#^Method Jerowork\\\\GraphqlAttributeSchema\\\\NodeParser\\\\EnumNodeParser\\:\\:getAttribute\\(\\) has parameter \\$reflector with generic class ReflectionClass but does not specify its types\\: T$#',
102108
'identifier' => 'missingType.generics',
@@ -344,7 +350,7 @@
344350
'path' => __DIR__ . '/src/SchemaBuilder.php',
345351
];
346352
$ignoreErrors[] = [
347-
'message' => '#^Parameter \\#1 \\$config of class GraphQL\\\\Type\\\\Schema constructor expects array\\{query\\?\\: \\(callable\\(\\)\\: \\(GraphQL\\\\Type\\\\Definition\\\\ObjectType\\|null\\)\\)\\|GraphQL\\\\Type\\\\Definition\\\\ObjectType\\|null, mutation\\?\\: \\(callable\\(\\)\\: \\(GraphQL\\\\Type\\\\Definition\\\\ObjectType\\|null\\)\\)\\|GraphQL\\\\Type\\\\Definition\\\\ObjectType\\|null, subscription\\?\\: \\(callable\\(\\)\\: \\(GraphQL\\\\Type\\\\Definition\\\\ObjectType\\|null\\)\\)\\|GraphQL\\\\Type\\\\Definition\\\\ObjectType\\|null, types\\?\\: \\(callable\\(\\)\\: iterable\\<callable\\(\\)\\: GraphQL\\\\Type\\\\Definition\\\\Type&GraphQL\\\\Type\\\\Definition\\\\NamedType\\>\\)\\|\\(callable\\(\\)\\: iterable\\<GraphQL\\\\Type\\\\Definition\\\\NamedType&GraphQL\\\\Type\\\\Definition\\\\Type\\>\\)\\|iterable\\<\\(callable\\(\\)\\: GraphQL\\\\Type\\\\Definition\\\\Type&GraphQL\\\\Type\\\\Definition\\\\NamedType\\)\\|\\(GraphQL\\\\Type\\\\Definition\\\\NamedType&GraphQL\\\\Type\\\\Definition\\\\Type\\)\\>\\|null, directives\\?\\: array\\<GraphQL\\\\Type\\\\Definition\\\\Directive\\>\\|null, typeLoader\\?\\: \\(callable\\(string\\)\\: \\(\\(GraphQL\\\\Type\\\\Definition\\\\NamedType&GraphQL\\\\Type\\\\Definition\\\\Type\\)\\|null\\)\\)\\|null, assumeValid\\?\\: bool\\|null, astNode\\?\\: GraphQL\\\\Language\\\\AST\\\\SchemaDefinitionNode\\|null, \\.\\.\\.\\}\\|GraphQL\\\\Type\\\\SchemaConfig, array\\{query\\: GraphQL\\\\Type\\\\Definition\\\\ObjectType, mutation\\: GraphQL\\\\Type\\\\Definition\\\\ObjectType, types\\: iterable\\<mixed\\>\\} given\\.$#',
353+
'message' => '#^Parameter \\#1 \\$config of class GraphQL\\\\Type\\\\Schema constructor expects array\\{description\\?\\: string\\|null, query\\?\\: \\(callable\\(\\)\\: \\(GraphQL\\\\Type\\\\Definition\\\\ObjectType\\|null\\)\\)\\|GraphQL\\\\Type\\\\Definition\\\\ObjectType\\|null, mutation\\?\\: \\(callable\\(\\)\\: \\(GraphQL\\\\Type\\\\Definition\\\\ObjectType\\|null\\)\\)\\|GraphQL\\\\Type\\\\Definition\\\\ObjectType\\|null, subscription\\?\\: \\(callable\\(\\)\\: \\(GraphQL\\\\Type\\\\Definition\\\\ObjectType\\|null\\)\\)\\|GraphQL\\\\Type\\\\Definition\\\\ObjectType\\|null, types\\?\\: \\(callable\\(\\)\\: iterable\\<callable\\(\\)\\: GraphQL\\\\Type\\\\Definition\\\\Type&GraphQL\\\\Type\\\\Definition\\\\NamedType\\>\\)\\|\\(callable\\(\\)\\: iterable\\<GraphQL\\\\Type\\\\Definition\\\\NamedType&GraphQL\\\\Type\\\\Definition\\\\Type\\>\\)\\|iterable\\<\\(callable\\(\\)\\: GraphQL\\\\Type\\\\Definition\\\\Type&GraphQL\\\\Type\\\\Definition\\\\NamedType\\)\\|\\(GraphQL\\\\Type\\\\Definition\\\\NamedType&GraphQL\\\\Type\\\\Definition\\\\Type\\)\\>\\|null, directives\\?\\: array\\<GraphQL\\\\Type\\\\Definition\\\\Directive\\>\\|null, typeLoader\\?\\: \\(callable\\(string\\)\\: \\(\\(GraphQL\\\\Type\\\\Definition\\\\NamedType&GraphQL\\\\Type\\\\Definition\\\\Type\\)\\|null\\)\\)\\|null, assumeValid\\?\\: bool\\|null, \\.\\.\\.\\}\\|GraphQL\\\\Type\\\\SchemaConfig, array\\{query\\: GraphQL\\\\Type\\\\Definition\\\\ObjectType, mutation\\: GraphQL\\\\Type\\\\Definition\\\\ObjectType, types\\: iterable\\<mixed\\>\\} given\\.$#',
348354
'identifier' => 'argument.type',
349355
'count' => 1,
350356
'path' => __DIR__ . '/src/SchemaBuilder.php',

src/Attribute/MapContext.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Jerowork\GraphqlAttributeSchema\Attribute;
6+
7+
use Attribute;
8+
9+
/**
10+
* Maps a resolver method parameter to an object stored in the GraphQL Context.
11+
*
12+
* The object is fetched from the Context by the parameter's type. A nullable parameter resolves to
13+
* null when the object is absent; a non-nullable parameter throws when it is absent.
14+
*/
15+
#[Attribute(Attribute::TARGET_PARAMETER)]
16+
final readonly class MapContext {}

0 commit comments

Comments
 (0)