GraphQL Express File Upload Middleware

1.0.0 · abandoned · verified Sun Apr 19

The `graphql-server-express-upload` package provides a middleware for Express.js applications to facilitate file uploads within GraphQL endpoints. Released with version 1.0.0 in 2016, it was designed to integrate specifically with `graphql-server-express` and relies on `multer` for parsing `multipart/form-data` requests. On the client-side, it required companion libraries like `apollo-upload-network-interface` because standard Apollo Client versions at the time did not natively support file uploads. This package introduced an `UploadedFile` scalar and expected a specific resolver implementation. However, both `graphql-server-express` and this package are now considered abandoned, with no updates since their initial release. Modern GraphQL ecosystems, particularly `@apollo/server`, have built-in, more robust file upload capabilities (often leveraging `graphql-upload`), making this package largely obsolete and incompatible with contemporary GraphQL server setups.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates setting up an Express server with `graphql-server-express-upload`, configuring `multer` for multipart processing, defining the `UploadedFile` scalar in the schema, and providing its custom resolver.

import express from 'express';
import { makeExecutableSchema } from '@graphql-tools/schema';
import { graphqlExpress, graphiqlExpress } from 'graphql-server-express';
import graphqlExpressUpload from 'graphql-server-express-upload';
import multer from 'multer';
import { Kind } from 'graphql';

const app = express();
const port = 4000;

// Multer setup for file uploads
const upload = multer({
  dest: '/tmp/uploads', // Ensure this directory exists or create it
});

// GraphQL Schema Definition
const typeDefs = `
  scalar UploadedFile

  type ProfilePicture {
    id: Int!
    url: String
    thumb: String
    square: String
    small: String
    medium: String
    large: String
    full: String
  }

  type Query {
    hello: String
  }

  type Mutation {
    uploadProfilePicture(id: Int!, files: [UploadedFile!]!): ProfilePicture
  }
`;

// Utility for UploadedFile scalar resolver (as shown in package README)
function parseJSONLiteral(ast) {
  switch (ast.kind) {
    case Kind.STRING:
    case Kind.BOOLEAN:
      return ast.value;
    case Kind.INT:
    case Kind.FLOAT:
      return parseFloat(ast.value);
    case Kind.OBJECT: {
      const value = Object.create(null);
      ast.fields.forEach(field => {
        value[field.name.value] = parseJSONLiteral(field.value);
      });
      return value;
    }
    case Kind.LIST:
      return ast.values.map(parseJSONLiteral);
    default:
      return null;
  }
}

// GraphQL Resolvers
const resolvers = {
  UploadedFile: {
    __parseLiteral: parseJSONLiteral,
    __serialize: value => value,
    __parseValue: value => value,
  },
  Query: {
    hello: () => 'Hello from GraphQL!',
  },
  Mutation: {
    async uploadProfilePicture(root, { id, files }, context) {
      console.log('Received upload for profile picture:', { id, files });
      // 'files' here would be an array of objects provided by Multer/graphqlExpressUpload
      // In a real app, process these files (e.g., save to disk, cloud storage).
      const uploadedFile = files[0]; // Example: assuming one file
      return {
        id,
        url: `http://example.com/uploads/${uploadedFile?.filename || 'dummy.jpg'}`,
        thumb: `http://example.com/thumbs/${uploadedFile?.filename || 'dummy.jpg'}`,
        square: `http://example.com/square/${uploadedFile?.filename || 'dummy.jpg'}`,
        small: `http://example.com/small/${uploadedFile?.filename || 'dummy.jpg'}`,
        medium: `http://example.com/medium/${uploadedFile?.filename || 'dummy.jpg'}`,
        large: `http://example.com/large/${uploadedFile?.filename || 'dummy.jpg'}`,
        full: `http://example.com/full/${uploadedFile?.filename || 'dummy.jpg'}`
      };
    },
  },
};

const schema = makeExecutableSchema({ typeDefs, resolvers });

// Express app setup for GraphQL endpoint
app.use(
  '/graphql',
  upload.array('files'), // Multer middleware to handle 'files' input field
  graphqlExpressUpload({ endpointURL: '/graphql' }), // THIS PACKAGE'S MIDDLEWARE
  graphqlExpress((req) => ({
    schema,
    context: {
      req, // Access to the original request
    },
  }))
);

// GraphiQL endpoint for testing
app.use(
  '/graphiql',
  graphiqlExpress({
    endpointURL: '/graphql',
  })
);

app.listen(port, () => {
  console.log(`Server running on http://localhost:${port}`);
  console.log(`GraphQL endpoint: http://localhost:${port}/graphql`);
  console.log(`GraphiQL endpoint: http://localhost:${port}/graphiql`);
});

view raw JSON →