Skip to content
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

Merged

Conversation

devkot
Copy link
Contributor

@devkot devkot commented Oct 3, 2021

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.

@apollo-cla
Copy link

@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/

@devkot devkot force-pushed the feature_add_allowBatchedHttpRequests_flag branch from 38bbdab to 1c8176d Compare October 3, 2021 18:41
@@ -298,6 +300,18 @@ export async function processHTTPRequest<TContext>(
parseGraphQLRequest(httpRequest.request, requestParams),
);

if (requests.length > 1 && options.allowBatchedHttpRequests === false) {
Copy link
Contributor Author

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

Copy link
Member

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.

@glasser glasser self-assigned this Oct 5, 2021
@glasser glasser added the 2021-10 label Oct 5, 2021
Copy link
Member

@glasser glasser left a 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) {
Copy link
Member

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,
Copy link
Member

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.',
Copy link
Member

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) => {
Copy link
Member

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 () => {
Copy link
Member

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),
Copy link
Member

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).

@@ -403,6 +403,16 @@ If this is set to any string value, use that value instead of the environment va
</td>
</tr>

##### `allowBatchedHttpRequests`
Copy link
Member

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.

</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.
Copy link
Member

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.

@devkot devkot force-pushed the feature_add_allowBatchedHttpRequests_flag branch from 1c8176d to bf3bf21 Compare October 12, 2021 21:15
@devkot
Copy link
Contributor Author

devkot commented Oct 12, 2021

This looks pretty good but I've got a few changes suggested. Let me know if you need my help doing them.

Thanks for the great feedback. It looks sensible and pretty straightforward - I'll let you know when it's ready for another review 😄

@devkot devkot force-pushed the feature_add_allowBatchedHttpRequests_flag branch from 53c868b to d14b37f Compare October 16, 2021 17:35
@devkot devkot requested a review from glasser October 16, 2021 17:50
@devkot
Copy link
Contributor Author

devkot commented Oct 19, 2021

That's all the changes now made @glasser. Feel free to have another look whenever you're free 😁

@devkot devkot force-pushed the feature_add_allowBatchedHttpRequests_flag branch from d14b37f to 785528a Compare October 27, 2021 21:22
@hwillson hwillson added 2021-11 and removed 2021-10 labels Nov 1, 2021
Stelios Kotanidis and others added 5 commits November 2, 2021 16:38
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
@glasser glasser force-pushed the feature_add_allowBatchedHttpRequests_flag branch from 785528a to e0139ab Compare November 2, 2021 23:39
@@ -298,6 +300,14 @@ export async function processHTTPRequest<TContext>(
parseGraphQLRequest(httpRequest.request, requestParams),
);

if (options.allowBatchedHttpRequests === false) {
Copy link
Member

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.

@glasser glasser merged commit 3b175dd into apollographql:main Nov 2, 2021
@glasser
Copy link
Member

glasser commented Nov 2, 2021

Thanks @devkot! This should get released this week.

@glasser
Copy link
Member

glasser commented Nov 5, 2021

This is released in v3.5.0.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 16, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants