Apollo Server 2 is officially end-of-life as of 22 October 2023.

Learn more about upgrading.

File uploads

Enabling file uploads in Apollo Server


⚠️ Apollo Server 2's file uploads feature is officially end-of-life as of 31 December 2022 and will no longer receive updates of any kind.

Learn more about this deprecation and end-of-life.

WARNING: The file upload mechanism described in this file (which we removed in Apollo Server 3) inherently exposes your server to CSRF mutation attacks. These attacks allow untrusted websites to ask users' browsers to send mutations to your Apollo Server which can execute even if your server's CORS security policy specifies that the origin in question should not be able to send that request. This is because the multipart/form-data content type that is parsed by the file upload feature is special-cased by browsers and can be sent in a POST request without the browser needing to "ask permission" via a "preflight" OPTIONS request. Attackers can run any mutation with your cookies, not just upload-specific mutations. Since Apollo Server v2.25.4, we no longer automatically enable this multipart/form-data parser unless you explicitly enable it with the uploads option to new ApolloServer() or if your schema uses the Upload scalar in it; in this case, your server will be protected from the CSRF mutation vulnerability. You can also pass uploads: false to new ApolloServer() in any version of Apollo Server 2 to ensure that this dangerous parser is disabled. If you actually use the upload feature (particularly if your app uses cookies for authentication), we highly encourage you to upgrade to Apollo Server v3.7 or newer and enable its CSRF prevention feature, or remove the use of uploads from your server.

Note: Apollo Server's built-in file upload mechanism is not fully supported in Node 14 and later, and it will be removed in Apollo Server 3. For details, see below.

For server integrations that support file uploads (e.g. Express, hapi, Koa), Apollo Server enables file uploads by default if your schema references the Upload type.

JavaScript
1const { ApolloServer, gql } = require('apollo-server');
2
3const typeDefs = gql`
4  type File {
5    filename: String!
6    mimetype: String!
7    encoding: String!
8  }
9
10  type Query {
11    uploads: [File]
12  }
13
14  type Mutation {
15    singleUpload(file: Upload!): File!
16  }
17`;
18
19const resolvers = {
20  Query: {
21    uploads: (parent, args) => {},
22  },
23  Mutation: {
24    singleUpload: (parent, args) => {
25      return args.file.then(file => {
26        //Contents of Upload scalar: https://github.com/jaydenseric/graphql-upload#class-graphqlupload
27        //file.createReadStream() is a readable node stream that contains the contents of the uploaded file
28        //node stream api: https://nodejs.org/api/stream.html
29        return file;
30      });
31    },
32  },
33};
34
35const server = new ApolloServer({
36  typeDefs,
37  resolvers,
38});
39
40server.listen().then(({ url }) => {
41  console.log(`🚀 Server ready at ${url}`);
42});

Note: When using typeDefs, Apollo Server adds scalar Upload to your schema, so any existing declaration of scalar Upload in the type definitions should be removed. If you create your schema with makeExecutableSchema and pass it to ApolloServer constructor using the schema param, make sure to include scalar Upload.

Uploads in Node 14 and later

Apollo Server's built-in support for file uploads relies on an old version of the graphql-upload npm package for backward compatibility. This old version is not fully compatible with Node 14.

To prevent similar backward compatibility issues in the future, Apollo Server 3 will not include built-in file upload support.

To use file uploads with Node 14, you can disable built-in support by passing uploads: false to the ApolloServer constructor. You can then install and use the lastest version of graphql-upload directly (see the documentation).

Feedback

Edit on GitHub

Forums