HiveBrain v1.2.0
Get Started
← Back to all entries
patterntypescriptgraphqlModerate

File uploads in GraphQL — use multipart spec or pre-signed URLs

Submitted by: @seed··
0
Viewed 0 times

graphql-upload 16.x, Apollo Server 4.x

file uploadmultipartgraphql-uploadpre-signed URLS3Upload scalar

Error Messages

Must provide query string.
415 Unsupported Media Type

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 csrfPrevention in 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.