patterntypescriptgraphqlModerate
File uploads in GraphQL — use multipart spec or pre-signed URLs
Viewed 0 times
graphql-upload 16.x, Apollo Server 4.x
file uploadmultipartgraphql-uploadpre-signed URLS3Upload scalar
Error Messages
Problem
GraphQL doesn't natively support file uploads — the spec only covers JSON. The
graphql-multipart-request-spec and graphql-upload library add multipart support, but they have known compatibility issues with Apollo Server 4+ and serverless environments.Solution
For simple cases, use
graphql-upload with Express. For production, prefer pre-signed URL uploads — the client uploads directly to S3, then passes the URL in a mutation.// Option A — graphql-upload (works with Apollo Server + express middleware)
import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.mjs';
app.use(graphqlUploadExpress({ maxFileSize: 10_000_000, maxFiles: 5 }));
// Resolver
const Mutation = {
uploadFile: async (_root, { file }: { file: Promise<FileUpload> }) => {
const { createReadStream, filename, mimetype } = await file;
// pipe stream to storage
},
};
// Option B — pre-signed URL (recommended for scale)
const Mutation = {
getUploadUrl: (_root, { filename, contentType }, ctx) =>
s3.getSignedUrlPromise('putObject', { Bucket: 'my-bucket', Key: filename, ContentType: contentType }),
confirmUpload: (_root, { key }, ctx) =>
db.asset.create({ data: { key, userId: ctx.userId } }),
};Why
Pre-signed URLs offload file transfer to S3 (or equivalent), eliminating bandwidth through your API server.
graphql-upload is simpler for development but doesn't scale and conflicts with Apollo Server 4's built-in body parsing.Gotchas
- Apollo Server 4 parses its own body — graphql-upload middleware must run BEFORE Apollo's handler
- graphql-upload conflicts with
csrfPreventionin Apollo Server 4 when using multipart - File size limits must be set both at the middleware level and at the infrastructure level (nginx, ALB)
- The Upload scalar from graphql-upload must be added to your schema type definitions
Context
GraphQL APIs that need to accept file uploads from clients
Revisions (0)
No revisions yet.