How to Use GraphQL Upload: Syntax, Example, and Tips
To use
graphql-upload, add the GraphQLUpload scalar to your schema and use it as an argument type for file uploads. Then, handle the uploaded file in your resolver by processing the FileUpload object which contains file stream and metadata.Syntax
The graphql-upload package provides a special scalar type GraphQLUpload to handle file uploads in GraphQL. You define an argument of this type in your mutation to accept files.
Example parts:
scalar Upload: Declares the upload scalar in your schema.upload: Upload!: Mutation argument to receive the file.FileUploadobject: The resolver receives this object withfilename,mimetype, andcreateReadStream()to access the file data.
graphql
scalar Upload type Mutation { singleUpload(file: Upload!): File! } type File { filename: String! mimetype: String! encoding: String! }
Example
This example shows a simple GraphQL server using graphql-upload to accept a single file upload. The resolver saves the file to disk and returns file info.
javascript
import { ApolloServer, gql } from 'apollo-server'; import { GraphQLUpload, graphqlUploadExpress } from 'graphql-upload'; import fs from 'fs'; import path from 'path'; const typeDefs = gql` scalar Upload type File { filename: String! mimetype: String! encoding: String! } type Mutation { singleUpload(file: Upload!): File! } `; const resolvers = { Upload: GraphQLUpload, Mutation: { async singleUpload(parent, { file }) { const { createReadStream, filename, mimetype, encoding } = await file; const stream = createReadStream(); const outPath = path.join(__dirname, 'uploads', filename); const out = fs.createWriteStream(outPath); stream.pipe(out); await new Promise((resolve, reject) => { out.on('finish', resolve); out.on('error', reject); }); return { filename, mimetype, encoding }; } } }; const server = new ApolloServer({ typeDefs, resolvers, uploads: false }); import express from 'express'; const app = express(); app.use(graphqlUploadExpress()); server.start().then(() => { server.applyMiddleware({ app }); app.listen({ port: 4000 }, () => { console.log('Server ready at http://localhost:4000' + server.graphqlPath); }); });
Output
Server ready at http://localhost:4000/graphql
Common Pitfalls
- Not adding
graphqlUploadExpress()middleware in your server setup causes uploads to fail. - Forgetting to declare
scalar Uploadin your schema leads to schema errors. - Not handling the file stream properly can cause memory leaks or incomplete uploads.
- Setting
uploads: falsein ApolloServer without middleware disables upload support.
graphql
/* Wrong: Missing middleware and scalar declaration */ const typeDefsWrong = gql` type Mutation { singleUpload(file: Upload!): File! } `; /* Right: Add scalar and middleware */ const typeDefsRight = gql` scalar Upload type Mutation { singleUpload(file: Upload!): File! } `; app.use(graphqlUploadExpress());
Quick Reference
| Step | Description |
|---|---|
| 1. Add scalar Upload | Declare scalar Upload in your GraphQL schema. |
| 2. Use Upload in mutation | Add an argument of type Upload! to your mutation. |
| 3. Add middleware | Use graphqlUploadExpress() middleware in your server. |
| 4. Handle file in resolver | Use createReadStream() to process the uploaded file. |
| 5. Return file info | Return file metadata like filename and mimetype from resolver. |
Key Takeaways
Always declare
scalar Upload in your schema to enable file uploads.Use
graphqlUploadExpress() middleware to parse multipart requests.Handle the file stream in your resolver to save or process the uploaded file.
Return useful file metadata to confirm successful upload.
Avoid disabling uploads by setting
uploads: false without middleware.