File Uploads
GraphQL Yoga supports the GraphQL Multipart Request Specification, allowing you to upload files and consume the binary data inside GraphQL Resolvers via HTTP.
In GraphQL Yoga, you consume uploaded files or blobs as WHATWG standard File
or Blob
objects you might be familiar from the browser's API. Check out the MDN documentation to learn more about File
objects
You can use any kind of client supports GraphQL Upload specification. Check out GraphQL Client solutions
Quick start
This guide will show you how to process a file upload in GraphQL Yoga in no time.
All you need to do is adding a File
scalar to your schema.
import { createYoga } from 'graphql-yoga'
import { createServer } from 'http'
// Provide your schema
const yoga = createYoga({
schema: createSchema({
typeDefs: /* GraphQL */ `
scalar File
type Query {
greetings: String!
}
type Mutation {
readTextFile(file: File!): String!
}
`,
resolvers: {
Query: {
greetings: () => 'Hello World!'
},
Mutation: {
readTextFile: async (_, { file }: { file: File }) => {
const textContent = await file.text()
return textContent
}
}
}
})
})
// Start the server and explore http://localhost:4000/graphql
const server = createServer(yoga)
server.listen(4000, () => {
console.info('Server is running on http://localhost:4000/graphql')
})
After, starting the server, you can use Curl for testing your endpoint.
curl localhost:4000/graphql \
-F operations='{ "query": "mutation ($file: File!) { readTextFile(file: $file) }", "variables": { "file": null } }' \
-F map='{ "0": ["variables.file"] }' \
-F 0=@mytext.txt
Disabling Multipart/File Upload Processing
If you want to disable multipart request processing for some reason, you can pass multipart: false
to prevent Yoga from handling multipart requests.
createYoga({ multipart: false })
Configuring Multipart Request Processing (only for Node.js)
In Node.js, you can configure the limits of the multipart request processing such as maximum allowed file size, maximum numbers of files, etc.
Fetch API's Request.formData
method doesn't have any options to configure the limits of Multipart request processing.
Instead we can configure our Fetch API ponyfill to manage that.
import { createFetch } from '@whatwg-node/fetch'
import { createYoga } from 'graphql-yoga'
createYoga({
fetchAPI: createFetch({
// We prefer `node-fetch` over `undici` and current unstable Node's implementation
useNodeFetch: true,
formDataLimits: {
// Maximum allowed file size (in bytes)
fileSize: 1000000,
// Maximum allowed number of files
files: 10,
// Maximum allowed size of content (operations, variables etc...)
fieldSize: 1000000,
// Maximum allowed header size for form data
headerSize: 1000000
}
})
})
Third Party Integrations
Usage with GraphQL Nexus
GraphQL Nexus is a popular library for building GraphQL schemas with TypeScript. It provides a convenient API for defining GraphQL types and resolvers.
import {
makeSchema,
scalarType,
mutationField,
queryField,
arg,
nonNull
} from 'nexus'
import { createYoga } from 'graphql-yoga'
import { createServer } from 'http'
const FileScalar = scalarType({
name: 'File',
asNexusMethod: 'file',
description: 'The `File` scalar type represents a file upload.',
sourceType: 'File'
})
const greetings = queryField('greetings', {
type: 'String',
resolve: () => 'Hello World!'
})
const readTextFile = mutationField('readTextFile', {
type: 'String',
args: { file: nonNull(arg({ type: 'File' })) },
resolve: async (parent, { file }, ctx) => {
const textContent = await file.text()
return textContent
}
})
const schema = makeSchema({
types: [FileScalar, greetings, readTextFile]
})
const yoga = createYoga({
schema: schema
})
// Start the server and explore http://localhost:4000/graphql
const server = createServer(yoga)
server.listen(4000, () => {
console.info('Server is running on http://localhost:4000/graphql')
})