Back to results for “HTTP & Web Servers”
Node.js › GraphQL

How would you handle file uploads in a GraphQL API, given GraphQL's standard JSON-based transport doesn't naturally support binary file data?

Intermediate

Answer

The graphql-upload package (implementing the community-established GraphQL multipart request specification) lets a client send a multipart/form-data request containing both the GraphQL operation and one or more file attachments together, with the server-side resolver receiving the uploaded file as a stream via a special Upload scalar type defined in the schema, bridging the gap between GraphQL's typical JSON transport and binary file data.
const { GraphQLUpload } = require('graphql-upload');

const resolvers = {
  Upload: GraphQLUpload,
  Mutation: {
    uploadAvatar: async (_, { file }) => {
      const { createReadStream, filename } = await file;
      const stream = createReadStream();
      await pipeline(stream, fs.createWriteStream(`./uploads/${filename}`));
      return { filename };
    },
  },
};
Real-world example A GraphQL API adds an 'uploadAvatar(file: Upload!): User' mutation using graphql-upload, letting clients upload a profile picture through the same GraphQL endpoint used for all other operations, rather than needing a completely separate REST endpoint just for file uploads.

Common follow-ups: Why can't a plain GraphQL query or mutation, sent as standard JSON, include binary file data directly?;What are the security considerations of accepting file uploads through this GraphQL mechanism, similar to the concerns discussed in File Uploads & Media Processing?