Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
4a7ba1a
add defer definition
devsergiy Aug 21, 2025
e0f49c4
add normalization rule to expand defer into inline defer per field
devsergiy Aug 26, 2025
06dd534
allow to merge non scalar fields with defer, allow to merge fields wi…
devsergiy Aug 27, 2025
10cf6ac
proper merge scalar fields with internal defer
devsergiy Aug 27, 2025
8926827
add tests with different defer on the same non scalar field
devsergiy Aug 27, 2025
2dc8822
add inline defer to operation normalizer
devsergiy Aug 27, 2025
1364780
mark defer paths in node suggestions
devsergiy Aug 28, 2025
e14ac40
add initial split of the fetches for defer
devsergiy Aug 29, 2025
48068c1
chore: cleanup after rebase
devsergiy Jan 8, 2026
31508a6
add comments
devsergiy Jan 11, 2026
5d838fe
pass defer id via fetch configuration
devsergiy Jan 11, 2026
23ef688
add defer to path configuration
devsergiy Jan 26, 2026
6199f95
cleanup skip include leftovers
devsergiy Jan 26, 2026
8ecdbaa
cleanup old defer directives
devsergiy Jan 26, 2026
3fccb96
pass defer id to the resolve.Field
devsergiy Jan 26, 2026
1fb48f6
setup postprocess structure for defer
devsergiy Jan 29, 2026
06aa764
implement defer postprocessor
devsergiy Jan 29, 2026
4824743
cleanup
devsergiy Feb 2, 2026
d2244ec
restructure
devsergiy Feb 2, 2026
054c0cb
rework handling of internal typename placeholder
devsergiy Feb 2, 2026
5dc0009
change defer internal definition
devsergiy Feb 2, 2026
548d015
skip internal directives in introspection
devsergiy Feb 2, 2026
8750578
draft: resolving defer response
devsergiy Feb 2, 2026
daffef7
ensure typenames, fix test case expectations
devsergiy Feb 15, 2026
ddcb424
rename print to enableRender, change usages of r.print to r.render()
devsergiy Feb 15, 2026
e347762
implement rendering defer response
devsergiy Feb 16, 2026
5ebde37
after rebase fixes
devsergiy Feb 17, 2026
b4df227
chore: improvements
devsergiy Mar 2, 2026
186780e
fix defer planning logic
devsergiy Mar 2, 2026
8ff579e
add more test cases
devsergiy Mar 2, 2026
efa0814
add todo; fix linter
devsergiy Mar 2, 2026
4cc28b6
rework defer rendering
devsergiy Mar 3, 2026
9b4369e
chore: fix
devsergiy Mar 4, 2026
d8ec33a
chore: add entity tests
devsergiy Mar 4, 2026
82ccd0c
chore: cleanup
devsergiy Mar 10, 2026
18845eb
change set of args to a struct
devsergiy Mar 10, 2026
915ea5f
pass defer id into required fields visitor
devsergiy Mar 10, 2026
50b0beb
refactor more methods signatures to use fieldRequirementsContext
devsergiy Mar 10, 2026
294cd87
alias deferred field requirements
devsergiy Mar 10, 2026
a1dfc51
pass whole defer info into required fields visitor
devsergiy Mar 10, 2026
7746a47
add required fields with defer directives applied
devsergiy Mar 10, 2026
5fa2794
handle edge case when we are adding requirementes for non deferred pa…
devsergiy Mar 10, 2026
78921e6
pass information about parent field defer into required fields visito…
devsergiy Mar 11, 2026
8db4c19
fix placing and scope of the defer typename placeholder
devsergiy Mar 12, 2026
2cafe94
update test expectations
devsergiy Mar 12, 2026
b4b6f95
restructure defer tests
devsergiy Mar 12, 2026
5acdf88
change require to assert in conditional round tripper
devsergiy Mar 12, 2026
702c2c2
chore: improve debug logs
devsergiy Mar 13, 2026
383d703
fix propagating defer parent ids to root nodes
devsergiy Mar 13, 2026
5d175e4
add have child fields to plan check
devsergiy Mar 13, 2026
c7a10f7
do not add an alias to typename
devsergiy Mar 13, 2026
f59c286
fix test expectations
devsergiy Mar 13, 2026
a06879a
simplify conditions
devsergiy Mar 18, 2026
8e6286b
properly set requirements for duplicated planner for the same field a…
devsergiy Mar 23, 2026
bfe2681
add draft of requires test
devsergiy Mar 23, 2026
af2ffed
add comments to required fields visitor
devsergiy Mar 24, 2026
ac6d08e
fix defer pointer comparison
devsergiy Mar 24, 2026
eb9ee84
fix mocks
devsergiy Mar 24, 2026
12ca35f
cleanup unused mocks
devsergiy Mar 24, 2026
cdc2b4a
tmp: refactor aliasing
devsergiy Mar 24, 2026
2661dde
fix naming
devsergiy Mar 25, 2026
aa8f198
add failing tests with errors
devsergiy Mar 25, 2026
7d4756f
implement proper defer error handling
devsergiy Mar 25, 2026
c941db5
add print helper
devsergiy Mar 25, 2026
c40756d
add arrays test
devsergiy Mar 26, 2026
065636d
add test with defer inside fragments and defer applied to fragment sp…
devsergiy Mar 26, 2026
e8ac9df
add draft of defer response plan
devsergiy Mar 26, 2026
69f4f4b
move internal defer helpers into ast
devsergiy Mar 26, 2026
9bcf37e
modify abstract selection rewriter to preserve internal defer ids
devsergiy Mar 26, 2026
a41c4e3
fix adding defer info to typename field
devsergiy Mar 26, 2026
bf85cbc
fix detecting nearest root node for the case of self jump
devsergiy Mar 27, 2026
b068c04
fix sorting defer ids in a proper order
devsergiy Mar 27, 2026
62d2417
fix compilation error after rebase
devsergiy Apr 6, 2026
f59a327
fix defer tests after rebase
devsergiy Apr 6, 2026
fb43df7
update base schema and introspection fixtures
devsergiy Apr 7, 2026
6ee4915
improve comments
devsergiy Apr 7, 2026
3d8c4c5
fix introspection datasource fixtures
devsergiy Apr 7, 2026
7ae5008
fix introspection tests
devsergiy Apr 7, 2026
081cac6
chore: gci
devsergiy Apr 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions execution/engine/config_factory_proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ func TestProxyEngineConfigFactory_EngineConfiguration(t *testing.T) {
expectedConfig.SetFieldConfigurations(expectedFieldConfigs)
sortFieldConfigurations(config.FieldConfigurations())

assert.Equal(t, graphqlGeneratorFullSchema, string(config.Schema().RawSchema()))
assert.Equal(t, expectedConfig, config)
})

Expand Down
31 changes: 25 additions & 6 deletions execution/engine/engine_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,19 +358,21 @@ type Language {
__typename: String!
}

"The 'Int' scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1."
"The ` + "`Int`" + ` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1."
scalar Int

"The 'Float' scalar type represents signed double-precision fractional values as specified by [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point)."
"The ` + "`Float`" + ` scalar type represents signed double-precision fractional values as specified by [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point)."
scalar Float

"The 'String' scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text."
"The ` + "`String`" + ` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text."
scalar String

"The 'Boolean' scalar type represents 'true' or 'false' ."
"The ` + "`Boolean` scalar type represents `true` or `false`." + `"
scalar Boolean

"The 'ID' scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as '4') or integer (such as 4) input value will be accepted as an ID."
"""
The ` + "`ID`" + ` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as "4") or integer (such as 4) input value will be accepted as an ID.
"""
scalar ID

"Directs the executor to include this field or fragment only when the argument is true."
Expand All @@ -395,7 +397,9 @@ directive @deprecated(
reason: String = "No longer supported"
) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION

"Exposes a URL that specifies the behavior of this scalar"
directive @specifiedBy(
"The URL that specifies the behavior of this scalar."
url: String!
) on SCALAR

Expand All @@ -406,6 +410,14 @@ All fields defined within a @oneOf input must be nullable in the schema.
"""
directive @oneOf on INPUT_OBJECT

"Directs the executor to defer this fragment when the if argument is true or undefined."
directive @defer(
"A unique identifier for the results."
label: String
"Controls whether the fragment will be deferred, usually via a variable."
if: Boolean! = true
) on FRAGMENT_SPREAD | INLINE_FRAGMENT

"""
A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document.
In some cases, you need to provide options to alter GraphQL's execution behavior
Expand Down Expand Up @@ -571,4 +583,11 @@ enum __TypeKind {
LIST
"Indicates this type is a non-null. 'ofType' is a valid field."
NON_NULL
}`
}

directive @__defer_internal(
id: String!
parentDeferId: String
"A unique identifier for the results."
label: String
) repeatable on FIELD`
4 changes: 4 additions & 0 deletions execution/engine/execution_engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ func (e *ExecutionEngine) Execute(ctx context.Context, operation *graphql.Reques
astnormalization.WithRemoveFragmentDefinitions(),
astnormalization.WithRemoveUnusedVariables(),
astnormalization.WithInlineFragmentSpreads(),
astnormalization.WithInlineDefer(),
)
if err != nil {
return err
Expand Down Expand Up @@ -243,6 +244,9 @@ func (e *ExecutionEngine) Execute(ctx context.Context, operation *graphql.Reques
operation.ComputeActualCost(costCalculator, e.config.plannerConfig, execContext.resolveContext.ActualListSizes)
}
return nil
case *plan.DeferResponsePlan:
_, err := e.resolver.ResolveGraphQLDeferResponse(execContext.resolveContext, p.Response, writer)
return err
case *plan.SubscriptionResponsePlan:
return e.resolver.ResolveGraphQLSubscription(execContext.resolveContext, p.Response, writer)
default:
Expand Down
Loading
Loading