Enhances Apollo for intuitive file uploads via GraphQL mutations or queries. Use with Apollo upload client.
- Express and Koa supported.
- Node >= 6.4 supported.
- MIT license.
Setup
Install
With NPM:
npm install apollo-upload-server --save
With Yarn:
yarn add apollo-upload-server
Server middleware
Add the server middleware just before graphql-server.
For Express:
import {apolloUploadExpress} from 'apollo-upload-server'
// ✂
app.use(
'/graphql',
bodyParser.json(),
apolloUploadExpress({
// Optional, defaults to OS temp directory
uploadDir: '/tmp/uploads'
}),
graphqlExpress(/* ✂ */)
)
// ✂
For Koa:
import {apolloUploadKoa} from 'apollo-upload-server'
// ✂
router.post(
'/graphql',
apolloUploadKoa({
// Optional, defaults to OS temp directory
uploadDir: '/tmp/uploads'
}),
graphqlKoa(/* ✂ */)
)
// ✂
Types
Add an input type to your schema. You can name it anything but it must have this shape:
input File {
name: String!
type: String!
size: Int!
path: String!
}
Client
Also setup Apollo upload client.
Usage
Once setup, you will be able to use File
objects, FileList
objects, or File
arrays within query or mutation input variables. See the client usage.
The files upload to a temp directory. The file path and metadata will be available under the variable name in the resolver in the shape of the input File
type in the GraphQL schema.
The resolver variable will hold an array if it is populated as a list (FileList
or File
array) on the client – even if the list has only 1 file.
Single file
In types:
type Mutation {
updateUserAvatar (userId: String!, avatar: File!): User!
}
In resolvers:
updateUserAvatar (root, {userId, avatar}) {
// Auth…
// Update avatar…
console.log(`New avatar for user ${userId} is ${avatar.size} bytes`)
// Return fresh user data…
}
See client usage for this example.
Multiple files
In types:
type Mutation {
updateGallery (galleryId: String!, images: [File!]!): Gallery!
}
In resolvers:
updateGallery (root, {galleryId, images}) {
// Auth…
// Update gallery…
console.log(`New images for gallery ${userId}:`)
images.forEach((image, index) => console.log(`Image ${index} is ${image.size} bytes`))
// Return fresh gallery data…
}
See client usage for this example.
Caveats
- No max upload file size option yet.