使用 nexus-prisma graphql 处理文件上传
Posted
技术标签:
【中文标题】使用 nexus-prisma graphql 处理文件上传【英文标题】:Handling file upload with nexus-prisma graphql 【发布时间】:2020-09-06 16:04:14 【问题描述】:我正在尝试将文件从我的前端应用上传到我的服务器 但我不断收到这个奇怪的错误,不知道为什么会这样。
错误是前端:
Variable "$file" got invalid value ; Expected type Upload. Upload value invalid.
后端出错:
GraphQLError: Upload value invalid.
at GraphQLScalarType.parseValue (/app/backend/node_modules/graphql-upload/lib/GraphQLUpload.js:66:11)
这就是我添加上传标量的方式
// scalars/upload.ts
import scalarType from "nexus/dist";
import GraphQLUpload from "graphql-upload";
export const Upload = scalarType(
name: "Upload",
asNexusMethod: "upload", // We set this to be used as a method later as `t.upload()` if needed
description: GraphQLUpload.description,
serialize: GraphQLUpload.serialize,
parseValue: GraphQLUpload.parseValue,
parseLiteral: GraphQLUpload.parseLiteral,
);
export default Upload;
// scalar/index.ts
export default as Upload from "./Upload";
// index.ts
import * as allTypes from "./resolvers";
import * as scalars from "./scalars";
const schema = makePrismaSchema(
types: [scalars, allTypes],
prisma:
datamodelInfo,
client: prisma,
,
...
// my mutation
t.string("uploadFile",
args:
file: arg( type: "Upload", nullable: false ),
,
resolve: async (_: any, file , : any) =>
console.log(file);
return "ok";
,
);
这就是我在我的 React/NextJS 应用程序中制作 uplaod 客户端的方式
// the link
const link = () =>
return createUploadLink(
uri: process.env.backend,
credentials: "include",
fetch,
);
;
// the mutation ( I use graphql codegen )
mutation TestUpload($file: Upload!)
uploadFile(file: $file)
const [upload] = useTestUploadMutation();
<input
type="file"
onChange=(e) =>
const files, validity = e.target;
if (validity.valid && files && files[0])
upload(
variables:
file: files[0],
,
);
/>
即使尝试使用我的前端应用程序以外的其他东西运行突变,我也会遇到同样的错误,所以我猜问题出在我的后端设置上,即使我搜索了很多方法来做到这一点,但似乎没有一个工作。
【问题讨论】:
【参考方案1】:我刚刚遇到了完全相同的问题。这解决了它。所以基本上手动定义上传而不是使用 GraphQLUpload
import objectType, scalarType from "@nexus/schema";
import GraphQLError from "graphql";
import * as FileType from "file-type";
export const Upload = scalarType(
name: "Upload",
asNexusMethod: "upload", // We set this to be used as a method later as `t.upload()` if needed
description: "desc",
serialize: () =>
throw new GraphQLError("Upload serialization unsupported.");
,
parseValue: async (value) =>
const upload = await value;
const stream = upload.createReadStream();
const fileType = await FileType.fromStream(stream);
if (fileType?.mime !== upload.mimetype)
throw new GraphQLError("Mime type does not match file content.");
return upload;
,
parseLiteral: (ast) =>
throw new GraphQLError("Upload literal unsupported.", ast);
,
);
export const File = objectType(
name: "File",
definition(t)
t.id("id");
t.string("path");
t.string("filename");
t.string("mimetype");
t.string("encoding");
,
);
【讨论】:
以上是关于使用 nexus-prisma graphql 处理文件上传的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 prisma 2 或 3 和 nexus 模式生成同时生成生成的 crud 和“ondelete 级联”
如何为 REST 和 GraphQL 使用相同的 RoleGuard?