From 0fbe7c51e0eabe4bf10492f501855c3699ef2bad Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Sun, 8 Mar 2026 16:55:38 -0500 Subject: [PATCH 1/2] Add inline value argument to @mock directive Adds a value: String argument to @mock that allows inline scalar mock values directly in the query without needing a mock file. The value and variant arguments are mutually exclusive. Co-Authored-By: Claude Opus 4.6 --- GAP-0/DRAFT.md | 93 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 82 insertions(+), 11 deletions(-) diff --git a/GAP-0/DRAFT.md b/GAP-0/DRAFT.md index 3fe25c9..a0f8b36 100644 --- a/GAP-0/DRAFT.md +++ b/GAP-0/DRAFT.md @@ -5,6 +5,7 @@ ```graphql directive @mock( variant: String + value: String ) on QUERY | MUTATION | SUBSCRIPTION | FIELD ``` @@ -61,6 +62,21 @@ the application. Multiple mocks for the same selection in an operation may be defined, allowing developers to swap out what is returned by changing the argument to `@mock`. +For scalar fields, `@mock` can also accept an inline {"value"} argument, +providing the mock response directly in the query without a mock file: + +```graphql example +query GetBusinessInfo { + business(id: "123") { + name @mock(value: "The Great British Bakery") + hours @mock(variant: "morning-only") { + open + close + } + } +} +``` + `@mock` may also be applied to operation roots, preventing a network request entirely: @@ -75,22 +91,62 @@ query GetBusinessInfo @mock(variant: "five-star-bakery") { # Directive -## Mock Variants +## Arguments + +`@mock` accepts two mutually exclusive arguments: {"variant"} and {"value"}. +Exactly one of these arguments must be provided. Providing both {"variant"} and +{"value"} in the same `@mock` application is a validation error. Providing +neither is also a validation error. + +### variant + +{"variant"} maps to a *mock variant id*. This uniquely identifies a +*mock value* (stored in the *mock file*) to return for the field or operation +where `@mock` is applied. + +### value + +{"value"} provides an inline *mock value* directly in the operation document. +When {"value"} is provided, the client uses the supplied string as the mock +response for the annotated field without consulting a *mock file*. -`@mock` accepts a required {"variant"} argument which maps to a *mock variant -id*. This uniquely identifies a *mock value* (stored in the *mock file*) to -return for the field or operation where `@mock` is applied. +{"value"} may only be applied to fields that resolve to +_[leaf types](https://spec.graphql.org/September2025/#sec-Leaf-Field-Selections)_ +(scalars and enums). It must not be applied to fields that return object types +or to operation roots. The client must coerce the string value to the field's +expected scalar type (for example, `"42"` becomes the integer {42} for an +{Int} field, and `"true"` becomes the boolean {true} for a {Boolean} field). + +```graphql example +query GetBusinessInfo { + business(id: "123") { + name @mock(value: "The Great British Bakery") + rating @mock(value: "4.5") + isOpen @mock(value: "true") + hours @mock(variant: "morning-only") { + open + close + } + } +} +``` + +Note: {"value"} is useful for quick, self-contained mocks of scalar fields +where the overhead of creating and maintaining a *mock file* entry is not +warranted. ## Returning Mock Data If `@mock` is applied to the operation's root field (e.g. {"query"}), the entire -response must be resolved from a *mock file*. +response must be resolved from a *mock file*. The {"value"} argument must not be +used on operation roots. If `@mock` is applied to non-root fields only, the client must transform the document to remove any selections which have `@mock` applied before sending the -request to the server. Mock values are resolved from a *mock file*. When the -server's response is received, the client merges each *mock value* into the -response before yielding to the application. +request to the server. For fields using {"variant"}, mock values are resolved +from a *mock file*. For fields using {"value"}, the mock value is the coerced +inline string. When the server's response is received, the client merges each +*mock value* into the response before yielding to the application. When `@mock` is applied to a field, the *mock value* must always be included in the response, regardless of other directives present on the same field. In @@ -99,7 +155,7 @@ data is always returned, irrespective of whether the field would otherwise be skipped or included based on those directives' conditions. Mock values must **not** be generated dynamically at runtime. Mock values must -be resolved from the *mock file*. +be resolved from the *mock file* or from the inline {"value"} argument. The mechanism for GraphQL clients running in a web browser or mobile client to read the *mock file* is implementation defined. See: @@ -107,8 +163,10 @@ read the *mock file* is implementation defined. See: ## Mock Files -Each operation or fragment that contains one or more `@mock` directives must -have an associated *mock file*. +Each operation or fragment that contains one or more `@mock` directives using +the {"variant"} argument must have an associated *mock file*. Operations or +fragments where all `@mock` directives use only the {"value"} argument do not +require a *mock file*. :: A *mock file* is a JSON file which maps *mock variant id* keys to a *mock variant*. @@ -280,6 +338,19 @@ If a *mock value* does not conform to the expected shape, client behavior is implementation-defined. Clients should validate mock values and provide helpful error messages during development. +### Inline Value Validation + +If {"value"} is applied to a field that does not resolve to a leaf type (scalar +or enum), the client must raise an error. + +If {"value"} is applied to an operation root, the client must raise an error. + +If the {"value"} string cannot be coerced to the field's expected scalar type, +the client must raise an error. + +If both {"variant"} and {"value"} are provided in the same `@mock` application, +the client must raise an error. + # Mock Generation The mechanism for generating and maintaining mock files is From 561bdff40f32cad92b4d9b1950244b4bbb8f6dc5 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Fri, 13 Mar 2026 14:20:52 -0500 Subject: [PATCH 2/2] human changes --- GAP-0/DRAFT.md | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/GAP-0/DRAFT.md b/GAP-0/DRAFT.md index a0f8b36..1b512c9 100644 --- a/GAP-0/DRAFT.md +++ b/GAP-0/DRAFT.md @@ -39,7 +39,7 @@ query GetBusinessInfo { } ``` -Mock data is stored and returned statically from JSON files: +Mock data may be stored and returned statically from JSON files: ```json example { @@ -53,30 +53,24 @@ Mock data is stored and returned statically from JSON files: } ``` -The client transforms the document to remove mocked -_[selections](https://spec.graphql.org/September2025/#Selection)_ before -executing or sending the request to the server. Upon receiving a response from -the server, mock values are merged into the response object before yielding to -the application. - -Multiple mocks for the same selection in an operation may be defined, allowing -developers to swap out what is returned by changing the argument to `@mock`. - For scalar fields, `@mock` can also accept an inline {"value"} argument, -providing the mock response directly in the query without a mock file: +providing the mock response directly in the operation without a mock file: ```graphql example query GetBusinessInfo { business(id: "123") { - name @mock(value: "The Great British Bakery") - hours @mock(variant: "morning-only") { - open - close - } + name + website @mock(value: "https://www.example.com") } } ``` +The client transforms the document to remove mocked +_[selections](https://spec.graphql.org/September2025/#Selection)_ before +executing or sending the request to the server. Upon receiving a response from +the server, mock values are merged into the response object before yielding to +the application. + `@mock` may also be applied to operation roots, preventing a network request entirely: @@ -95,8 +89,7 @@ query GetBusinessInfo @mock(variant: "five-star-bakery") { `@mock` accepts two mutually exclusive arguments: {"variant"} and {"value"}. Exactly one of these arguments must be provided. Providing both {"variant"} and -{"value"} in the same `@mock` application is a validation error. Providing -neither is also a validation error. +{"value"} in the same `@mock` application is a validation error. ### variant