-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Feature add allow batched http requests flag #5778
Feature add allow batched http requests flag #5778
Conversation
@devkot: Thank you for submitting a pull request! Before we can merge it, you'll need to sign the Apollo Contributor License Agreement here: https://contribute.apollographql.com/ |
38bbdab
to
1c8176d
Compare
@@ -298,6 +300,18 @@ export async function processHTTPRequest<TContext>( | |||
parseGraphQLRequest(httpRequest.request, requestParams), | |||
); | |||
|
|||
if (requests.length > 1 && options.allowBatchedHttpRequests === false) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't figure out a nice way of setting defaults in the GraphQLServer options so I've left this conditional naive for now - I'd be keen to improve this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should just block the array format entirely, whether or not there are multiple operations.
Let's say you write a client library that for simplicity always sends requests as an array. (I believe the Apollo Client batch HTTP link does this.) It would be better if every attempt to use the batch HTTP link against this server failed rather than only concurrent attempts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks pretty good but I've got a few changes suggested. Let me know if you need my help doing them.
@@ -298,6 +300,18 @@ export async function processHTTPRequest<TContext>( | |||
parseGraphQLRequest(httpRequest.request, requestParams), | |||
); | |||
|
|||
if (requests.length > 1 && options.allowBatchedHttpRequests === false) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should just block the array format entirely, whether or not there are multiple operations.
Let's say you write a client library that for simplicity always sends requests as an array. (I believe the Apollo Client batch HTTP link does this.) It would be better if every attempt to use the batch HTTP link against this server failed rather than only concurrent attempts.
@@ -298,6 +300,18 @@ export async function processHTTPRequest<TContext>( | |||
parseGraphQLRequest(httpRequest.request, requestParams), | |||
); | |||
|
|||
if (requests.length > 1 && options.allowBatchedHttpRequests === false) { | |||
return throwHttpGraphQLError( | |||
500, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a client error like invalid JSON and should probably be 400, not a server error.
500, | ||
[ | ||
new Error( | ||
'GraphQL Query Batching is not allowed by Apollo Server, but the request contained multiple queries.', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes it sound like the AS project does not support batching, rather than the configuration. I would suggest something like "Operation batching disabled."
operationName: 'testX', | ||
}, | ||
]); | ||
return req.then((res) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test is already async so you can just const res = await request(app)....
request: new MockReq(), | ||
}; | ||
|
||
it('succeeds when there are multiple queries in the request', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test name is inaccurate (though I'm also suggesting you change the logic)
options: { | ||
debug: false, | ||
schema, | ||
schemaHash: generateSchemaHash(schema), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please rebase your PR and replace this line with schemaHash: 'deprecated'
(I just changed the thing this was copied from).
docs/source/api/apollo-server.md
Outdated
@@ -403,6 +403,16 @@ If this is set to any string value, use that value instead of the environment va | |||
</td> | |||
</tr> | |||
|
|||
##### `allowBatchedHttpRequests` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be moved to the "Networking options" section from the "Debugging options" section.
docs/source/api/apollo-server.md
Outdated
</td> | ||
<td> | ||
|
||
Controls whether to allow batching multiple Queries in a single HTTP Request. Defaults to `true`. If the GraphQL Server has this flag set to `false` and a request comes in with more than one query, an error will be thrown. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can link to https://www.apollographql.com/docs/apollo-server/requests/#batching (as ../requests/#batching
) and probably mention that option on that page too.
1c8176d
to
bf3bf21
Compare
Thanks for the great feedback. It looks sensible and pretty straightforward - I'll let you know when it's ready for another review 😄 |
53c868b
to
d14b37f
Compare
That's all the changes now made @glasser. Feel free to have another look whenever you're free 😁 |
d14b37f
to
785528a
Compare
Allow specifying allowBatchedHttpRequests in the ApolloServer constructor which will be used to disable requests that batch multiple queries in a single request.
Using the allowBatchedHttpRequests coming from the GraphQLServerOptions to limit requests to a single query per request. This defaults to True for backwards-compatibility reasons.
* Implement requested changes and update docs
785528a
to
e0139ab
Compare
@@ -298,6 +300,14 @@ export async function processHTTPRequest<TContext>( | |||
parseGraphQLRequest(httpRequest.request, requestParams), | |||
); | |||
|
|||
if (options.allowBatchedHttpRequests === false) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to move this up a few lines — no use parsing the request if we're going to immediately throw.
Thanks @devkot! This should get released this week. |
This is released in v3.5.0. |
As per #5686, add the ability to opt out of batches queries in a single HTTP request. This defaults to true for backwards compatibility reasons.
This new feature has a few benefits such as performance as the response in a batch would be bounded by the slowest query. It can also be used as an increased security measure like preventing bad actors from using batching to validate 2FA pin codes by using different permutations.