No description, website, or topics provided.
Branch: master
Clone or download
Latest commit 01d0d5c Feb 9, 2019
Type Name Latest commit message Commit time
Failed to load latest commit information.
.vscode Misc updates Aug 22, 2018
client chore: update deps Feb 9, 2019
server chore: update deps Feb 9, 2019
LICENSE Initial commit Mar 30, 2018 chore: update deps Feb 9, 2019


This app demonstrates how to add file upload support to PostGraphile using the GraphQL Multipart Request Spec.



Quick Start

Clone this repo.

In one terminal:

cd server
createdb upload_example
psql -d upload_example -f schema.sql
yarn start

In another terminal:

cd client
yarn start

The app should now be fully functional at localhost:3000. Uploaded files will be stored locally in /server/uploads.

How does it work?

The server code should be relatively straightforward if you're familiar with PostGraphile. The graphql-upload middleware handles the multipart requests using busboy. The postgraphile-plugin-upload-field plugin for PostGraphile is minimally documented, but briefly, match is a function used to specify the file upload metadata columns and resolve is a function that handles the actual file upload stream.

The client is full of React/Apollo boilerplate. The unique parts are:

Preserving metadata

By default, the example app only stores the local file path to Postgres. To preserve additional metadata, change the header_image_file column type to JSONB and replace the resolveUpload function with the following:

async function resolveUpload(upload) {
  const { filename, mimetype, encoding, createReadStream } = upload;
  const stream = createReadStream();
  // Save file to the local filesystem
  const { id, path } = await saveLocal({ stream, filename });
  // Return metadata to save it to Postgres
  return {

After making this change, you'll also need to update the client app to use the path property of the object.

For a more robust solution, consider using something like postgraphile-plugin-derived-field to expose URLs through GraphQL instead of exposing the raw path/metadata.

If you're streaming file uploads to an object storage service such as S3, you can also use the derived field plugin to generate pre-signed URLs for clients.