0
0
GraphqlDebug / FixBeginner · 4 min read

How to Handle File Upload in Apollo Server Easily

To handle file uploads in Apollo Server, use the Apollo Server Uploads feature by enabling the graphql-upload middleware and defining your schema with the Upload scalar type. Then, in your resolver, process the uploaded file stream properly to save or use the file.
🔍

Why This Happens

Many developers try to upload files in Apollo Server without enabling the necessary middleware or without using the Upload scalar type. Apollo Server does not handle file uploads by default, so missing these steps causes errors or no file data received.

javascript
const { ApolloServer, gql } = require('apollo-server');

const typeDefs = gql`
  type Mutation {
    uploadFile(file: String!): Boolean
  }
`;

const resolvers = {
  Mutation: {
    uploadFile: (parent, { file }) => {
      console.log(file); // file is just a string, not a file upload
      return true;
    },
  },
};

const server = new ApolloServer({ typeDefs, resolvers });

server.listen().then(({ url }) => {
  console.log(`Server ready at ${url}`);
});
Output
Error or unexpected behavior: file is just a string, no file upload stream received.
🔧

The Fix

Use the graphql-upload package which Apollo Server supports. Define the Upload scalar in your schema and enable the upload middleware. In your resolver, handle the file as a promise that resolves to a file stream you can save or process.

javascript
const { ApolloServer, gql } = require('apollo-server');
const fs = require('fs');
const { GraphQLUpload } = require('graphql-upload');

const typeDefs = gql`
  scalar Upload

  type Mutation {
    uploadFile(file: Upload!): Boolean
  }
`;

const resolvers = {
  Upload: GraphQLUpload,
  Mutation: {
    uploadFile: async (parent, { file }) => {
      const { createReadStream, filename } = await file;
      return new Promise((resolve, reject) => {
        const stream = createReadStream();
        const out = fs.createWriteStream(`./uploads/${filename}`);
        stream.pipe(out);
        out.on('finish', () => resolve(true));
        out.on('error', reject);
      });
    },
  },
};

const server = new ApolloServer({ typeDefs, resolvers });

server.listen().then(({ url }) => {
  console.log(`Server ready at ${url}`);
});
Output
Server ready at http://localhost:4000/ File uploads are saved to ./uploads/ folder successfully.
🛡️

Prevention

Always include the Upload scalar and enable the graphql-upload middleware when you expect file uploads. Validate file size and type in your resolver to avoid bad uploads. Use clear error handling to inform users of upload issues.

Keep your uploads folder secure and clean up old files regularly. Test uploads with tools like GraphQL Playground or Apollo Studio to confirm your setup works.

⚠️

Related Errors

Common errors include:

  • Missing multipart middleware: Happens if graphql-upload is not enabled.
  • File stream not received: Caused by incorrect schema type or resolver handling.
  • Upload scalar not defined: Forgetting to add scalar Upload in schema.

Fix these by following the correct setup steps and checking your server logs.

Key Takeaways

Enable the graphql-upload middleware to support file uploads in Apollo Server.
Define the Upload scalar type in your GraphQL schema for file inputs.
Handle file streams properly in resolvers to save or process uploads.
Validate and secure uploaded files to prevent issues.
Test uploads thoroughly to catch configuration errors early.