GraphQL Yoga 文件上传功能详解
2025-07-07 01:57:20作者:彭桢灵Jeremy
概述
GraphQL Yoga 作为一款功能强大的 GraphQL 服务器实现,提供了对 GraphQL 多部分请求规范(GraphQL Multipart Request Specification)的完整支持。这意味着开发者可以轻松实现文件上传功能,并通过 HTTP 在 GraphQL 解析器中处理二进制数据。
核心特性
GraphQL Yoga 处理上传文件时,会将其转换为符合 WHATWG 标准的 File
或 Blob
对象。这些对象与浏览器 API 中的文件对象完全一致,使得前端开发者能够无缝过渡到服务端处理。
快速入门
1. 添加 File 标量类型
首先,你需要在 GraphQL 模式中定义一个 File
标量类型:
scalar File
type Mutation {
readTextFile(file: File!): String!
saveFile(file: File!): Boolean!
}
2. 实现解析器
在解析器中,你可以直接使用 File
对象提供的方法处理上传的文件:
Mutation: {
readTextFile: async (_, { file }: { file: File }) => {
const textContent = await file.text()
return textContent
},
saveFile: async (_, { file }: { file: File }) => {
try {
const fileArrayBuffer = await file.arrayBuffer()
await fs.promises.writeFile(
path.join(__dirname, file.name),
Buffer.from(fileArrayBuffer)
)
return true
} catch (e) {
return false
}
}
}
3. 测试上传功能
可以使用 curl 命令测试文件上传功能:
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
高级配置
禁用文件上传
如果需要禁用多部分请求处理,可以在创建 Yoga 实例时设置:
createYoga({ multipart: false })
配置上传限制(仅限 Node.js 环境)
在 Node.js 环境中,可以配置多部分请求处理的各项限制:
import { createFetch } from '@whatwg-node/fetch'
createYoga({
fetchAPI: createFetch({
formDataLimits: {
fileSize: 1000000, // 最大文件大小(字节)
files: 10, // 最大文件数量
fieldSize: 1000000, // 最大内容大小
headerSize: 1000000 // 最大头部大小
}
})
})
第三方集成方案
与 GraphQL Nexus 集成
GraphQL Nexus 是一个流行的 TypeScript GraphQL 模式构建库。集成示例如下:
const FileScalar = scalarType({
name: 'File',
asNexusMethod: 'file',
description: '文件上传标量类型',
sourceType: 'File'
})
const readTextFile = mutationField('readTextFile', {
type: 'String',
args: { file: nonNull(arg({ type: 'File' })) },
resolve: async (_, { file }) => {
return await file.text()
}
})
与 S3 存储集成
可以将上传的文件直接存储到 S3 或其他兼容存储服务:
const client = new S3Client({})
Mutation: {
upload: async (_, { file }: { file: File }) => {
await client.send(
new PutObjectCommand({
Bucket: 'test-bucket',
Key: file.name,
Body: Buffer.from(await file.arrayBuffer())
})
)
return true
}
}
最佳实践
- 文件大小验证:始终在业务逻辑中验证文件大小,即使配置了服务器限制
- 文件类型检查:通过文件扩展名或 MIME 类型验证文件格式
- 错误处理:为文件操作提供详细的错误反馈
- 流式处理:对于大文件,考虑使用流式处理而非完全加载到内存
通过 GraphQL Yoga 的文件上传功能,开发者可以轻松构建支持文件上传的 GraphQL API,同时保持代码的简洁性和可维护性。