Skip to content

Commit

Permalink
Increase default body-parser limit for standalone server (#7172)
Browse files Browse the repository at this point in the history
In `apollo-server` (v3 standalone equivalent), the default limit for the
`body-parser` package was `50mb`. This restores the previous limit
and adds a test to confirm it remains at least > the default (100KiB).

<!--
First, 🌠 thank you 🌠 for taking the time to consider a contribution to
Apollo!

Here are some important details to follow:

* ⏰ Your time is important
To save your precious time, if the contribution you are making will take
more
than an hour, please make sure it has been discussed in an issue first.
          This is especially true for feature requests!
* 💡 Features
Feature requests can be created and discussed within a GitHub Issue. Be
sure to search for existing feature requests (and related issues!) prior
to
opening a new request. If an existing issue covers the need, please
upvote
that issue by using the 👍 emote, rather than opening a new issue.
* 🔌 Integrations
Apollo Server has many web-framework integrations including Express,
Koa,
Hapi and more. When adding a new feature, or fixing a bug, please take a
peak and see if other integrations are also affected. In most cases, the
fix can be applied to the other frameworks as well. Please note that,
since new web-frameworks have a high maintenance cost, pull-requests for
new web-frameworks should be discussed with a project maintainer first.
* 🕷 Bug fixes
These can be created and discussed in this repository. When fixing a
bug,
please _try_ to add a test which verifies the fix. If you cannot, you
should
still submit the PR but we may still ask you (and help you!) to create a
test.
* 📖 Contribution guidelines
Follow
https://github.com/apollographql/apollo-server/blob/main/CONTRIBUTING.md
when submitting a pull request. Make sure existing tests still pass, and
add
          tests for all new behavior.
* ✏️ Explain your pull request
Describe the big picture of your changes here to communicate to what
your
pull request is meant to accomplish. Provide 🔗 links 🔗 to associated
issues!

We hope you will find this to be a positive experience! Open source
contribution can be intimidating and we hope to alleviate that pain as
much as possible. Without following these guidelines, you may be missing
context that can help you succeed with your contribution, which is why
we encourage discussion first. Ultimately, there is no guarantee that we
will be able to merge your pull-request, but by following these
guidelines we can try to avoid disappointment.
-->

Co-authored-by: David Glasser <glasser@apollographql.com>
  • Loading branch information
trevor-scheer and glasser committed Nov 19, 2022
1 parent 45856e1 commit 7ff96f5
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 8 deletions.
5 changes: 5 additions & 0 deletions .changeset/stale-ligers-impress.md
@@ -0,0 +1,5 @@
---
'@apollo/server': patch
---

startStandaloneServer: Restore body-parser request limit to 50mb (as it was in the `apollo-server` package in Apollo Server 3)
13 changes: 7 additions & 6 deletions docs/source/api/standalone.mdx
Expand Up @@ -9,7 +9,7 @@ This API reference documents the `startStandaloneServer` function.

## Overview

This `startStandaloneServer` function helps you get started with Apollo Server quickly. This function is recommended for all projects that don't require serverless support or a particular Node.js framework (such as Fastify). Under the hood, the `startStandaloneServer` function uses Apollo Server 4's Express integration (i.e., [`expressMiddleware`](./express-middleware)).
This `startStandaloneServer` function helps you get started with Apollo Server quickly. This function is recommended for all projects that don't require serverless support or a particular Node.js framework (such as Fastify). Under the hood, the `startStandaloneServer` function uses Apollo Server 4's Express integration (i.e., [`expressMiddleware`](./express-middleware)).

Because it sets helpful defaults, this function is less configurable than other Apollo Server integrations. Complex projects might eventually need to [swap to using `expressMiddleware`](#swapping-to-expressmiddleware) (this process is straightforward).

Expand All @@ -30,7 +30,7 @@ const server = new ApolloServer({ typeDefs, resolvers });
// `startStandaloneServer` returns a `Promise` with the
// the URL that the server is listening on.
const { url } = await startStandaloneServer(server); //highlight-line
```
```

</MultiCodeBlock>

Expand Down Expand Up @@ -59,7 +59,7 @@ The `startStandaloneServer` function's second optional argument is an object for

<td>

An optional asynchronous [`context` initialization function](../data/resolvers#the-context-argument).
An optional asynchronous [`context` initialization function](../data/resolvers#the-context-argument).

The `context` function should return an object that all your server's resolvers share during an operation's execution. This enables resolvers to share helpful context values, such as a database connection.

Expand Down Expand Up @@ -91,7 +91,7 @@ If no `port` is specified, this defaults to using `{port: 4000}`.
</tbody>
</table>

### Example
### Example

Below is a full example of setting up `startStandaloneServer`:

Expand Down Expand Up @@ -196,7 +196,8 @@ await server.start();
// and our expressMiddleware function.
app.use('/',
cors<cors.CorsRequest>(),
bodyParser.json(),
// 50mb is the limit that `startStandaloneServer` uses, but you may configure this to suit your needs
bodyParser.json({ limit: '50mb' }),
// expressMiddleware accepts the same arguments:
// an Apollo Server instance and optional configuration options
expressMiddleware(server, {
Expand All @@ -208,4 +209,4 @@ app.use('/',
await new Promise<void>(resolve => httpServer.listen({ port: 4000 }, resolve));
console.log(`🚀 Server ready at http://localhost:4000/`);
```
</MultiCodeBlock>
</MultiCodeBlock>
@@ -1,6 +1,7 @@
import { describe, expect, it } from '@jest/globals';
import fetch from 'node-fetch';
import { ApolloServer } from '../..';
import { startStandaloneServer } from '../../standalone';
import { describe, it } from '@jest/globals';

describe('Typings: TContext inference', () => {
it('correctly infers BaseContext when no `context` function is provided', async () => {
Expand Down Expand Up @@ -103,3 +104,41 @@ describe('Typings: TContext inference', () => {
await server.stop();
});
});

describe('Configuration', () => {
it('allows > 100KiB bodies to be sent (body-parser default)', async () => {
const server = new ApolloServer({
typeDefs: `type Query { hello: String }`,
resolvers: {
Query: {
hello: () => 'hello world!',
},
},
});

const { url } = await startStandaloneServer(server, {
listen: { port: 0 },
});

const excessivelyLargeBody = JSON.stringify({
query: `{hello}`,
variables: { foo: 'a'.repeat(102400) },
});

// 100kib limit = 102400 bytes
expect(Buffer.byteLength(excessivelyLargeBody)).toBeGreaterThan(102400);

const result = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: excessivelyLargeBody,
});
const { data } = await result.json();

expect(data.hello).toEqual('hello world!');

await server.stop();
});
});
6 changes: 5 additions & 1 deletion packages/server/src/standalone/index.ts
Expand Up @@ -56,7 +56,11 @@ export async function startStandaloneServer<TContext extends BaseContext>(
await server.start();

const context = options?.context ?? (async () => ({} as TContext));
app.use(cors(), bodyParser.json(), expressMiddleware(server, { context }));
app.use(
cors(),
bodyParser.json({ limit: '50mb' }),
expressMiddleware(server, { context }),
);

const listenOptions = options?.listen ?? { port: 4000 };
// Wait for server to start listening
Expand Down

0 comments on commit 7ff96f5

Please sign in to comment.