-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC] Executing multiple operations in a query #375
Comments
Immediate hunch: how is this different from:
I.e., if you fragment the queries, then building up one which does both seems to be as easy as doing
and this only requires a single query. I think this should be part of a discussion, simply because the added functionality needs to have something which cannot be obtained by simply fragmenting the query. YMMV of course. |
@jlouis - its different because it allows 2 major things
In your example above the $droidId can't be an output of A that is fed into B Also in your example above the data for |
This is aging, but it would be interesting to see a more holistic approach to batch requests. I think it probably requires a new algorithm other than Execute |
It seems to me that this task should be solved at the transport level. Query batching is a well-known concept within which it is possible to solve the described problem. Several queries are transmitted in one (HTTP) request, then the server parses them and passes to the graphql engine for execution, making all the necessary transformations, variables matching etc. That is, I want to say that this is not part of the graphql specification, this can be a part of the transport protocol. Related to graphql/graphql-over-http#5 |
though it does seem to make sense as a transport spec, there is this section in the main spec that does prescribe a single for example, a primitive |
It should be implemented for mutations as well: And to make it even better for permissions checks there should be a way to specify how non-depend mutations are executed: in parallel or in sequence order. Or may be a way to specify dependent mutations without data exchange between mutations (so all non-dependent can be executed in parallel). |
The GraphQL HTTP spec started an early RFC. https://github.com/graphql/graphql-over-http/blob/main/rfcs/Batching.md |
RFC - Executing multiple operations in a query
Today you can define multiple operations in the one query document but the specification states you can only execute one of them at a time. So given :
You must indicate which operation to run. See http://facebook.github.io/graphql/October2016/#sec-Executing-Requests
This RFC proposes that we add the ability to run multiple operations at the one time.
Naming the operation
We propose that a list of operations be able to be given to the execution
ExecuteRequest(schema, document, operationNames, variableValues, initialValue)
GetOperations(document, operationNames)
Executing each operation
The list of operations will be executed in the order specified. A list of
ExecutionResult
s will be produced that represent each operation.If an operation is a mutation, then the serial execution will be applied to it as per a single operation.
The finaly result will be a single
ExecutionResult
that contains the list ofExecutionResult
for each operation executed. This preserves the current expected signature from an graphql execution.However like subsciptions, the top level data iterm is a proscibed shape, that is list of
ExecutionResult
Operation dependencies
Directive capabilities can create dependencies between the execution of operations.
For example B might depend on A executing first. If the graphql implementation detects such a dependency then it will wait for dependee operation (say A) to complete before executing the dependent operation (say B)
If not dependencies are detected, or the graphql implementation does not allow dependencies, then the operations can be executed in parralel, assuming they are query operations.
Variables given to each operation
The variables that are specified on the original execution will be given to each operation.
The graphql implementation is free to augment those variables with new values as it executes.
New variables will be subject to the same validation rules as the initial variables.
Capabilities unlocked because of multiple operations
Multiple operations allows for more efficient graphql queries. Multiple queries can be sent over slow mobile networks (which preparsed queries make even more efficient) and results can be sent back as soon as thye are obtained
One you have the ability to have multiple operations, you can introduce new capabilities like variable export.
This RFC is not concerned with defining exactly how this happens but having multiple operations is a pre-cursor to such capabilities.
For examaple imagine a query like
Output values from operation A would be exported as the variables named "droidId", "r2d2Friends", and "friendNames"
The operation B would be detected to be dependent on operation A and would be executed after operation A completes. It would receive the value of "droidId" as a variable from operation A
Open Questions
The return shape of the results is an open question. Should it be a list (as proposed) or be async iterator in line with subscription operations.
When the returned results are
Promise
based then the distinction between list of Promise and async iterator ofPromise
is very small and we prefer the simple list.There is a symmetry between a list of operations as input and a list of results as output.
Current implementations
Sangria has this capability today sangria-graphql.org/learn/#batch-executor and graphql-java has a PR exploring the idea graphql-java/graphql-java#808
The text was updated successfully, but these errors were encountered: