我想通过GraphQL上传文件,并遵循此article。
这是我的模式:
Ares=[]
Bres=[]
a = [4, 5, 2]
b = [3, 5, 4]
al=len(a)
for i in range(0,al):
if a[i]>b[i]:
Ares.append("1")
if a[i]<b[i]:
Ares.append("0")
if b[i]>a[i]:
Bres.append("1")
if b[i]<a[i]:
Bres.append("0")
if a[i]==b[i]:
Ares.append("0")
Bres.append("0")
Adata= list(map(int, Ares))
Aresult=sum(list(Adata))
Bdata= list(map(int, Bres))
Bresult=sum(list(Bdata))
RES=[Aresult,Bresult]
print(RES)
但是,当我运行应用程序时,这会给我这个错误:
未知类型“上传”。您是说“浮动”吗?
上面的文章之后,Apollo Server将自动生成Upload标量,但是为什么会发生这种情况?
还手动定义了“上传标量”也无效:
extend type Mutation {
bannerAdd(
title: String!
image: Upload
): ID
}
给我这个错误:
错误:只能有一种名为“上传”的类型。
我的代码似乎没有错。有什么我想念的吗?使用Node @ 10.14.2,Apollo Server @ 2.6.1,Apollo Server Express@2.6.1和polka@0.5.2。
任何建议都会非常感谢。
答案 0 :(得分:2)
使用Apollo服务器的GraphQLUpload
解决此问题,以创建名为FileUpload
的自定义标量。
const {ApolloServer, gql, GraphQLUpload} = require('apollo-server');
const typeDefs = gql`
scalar FileUpload
type File {
filename: String!
mimetype: String!
encoding: String!
}
type Query {
uploads: [File]
}
type Mutation {
singleUpload(file: FileUpload!): File!
}
`;
const resolvers = {
FileUpload: GraphQLUpload,
Query: {
uploads: (parent, args) => {},
},
Mutation: {
singleUpload: async (_, {file}) => {
const {createReadStream, filename, mimetype, encoding} = await file;
const stream = createReadStream();
// Rest of your code: validate file, save in your DB and static storage
return {filename, mimetype, encoding};
},
},
};
const server = new ApolloServer({
typeDefs,
resolvers,
});
server.listen().then(({url}) => {
console.log(`? Server ready at ${url}`);
});
您还需要安装apollo-upload-client软件包。
import React from 'react';
import ReactDOM from 'react-dom';
import { ApolloClient, InMemoryCache, ApolloProvider, gql, useMutation } from '@apollo/client';
import { createUploadLink } from 'apollo-upload-client';
const httpLink = createUploadLink({
uri: 'http://localhost:4000'
});
const client = new ApolloClient({
link: httpLink,
cache: new InMemoryCache()
});
const UPLOAD_FILE = gql`
mutation uploadFile($file: FileUpload!) {
singleUpload(file: $file) {
filename
mimetype
encoding
}
}
`;
function FileInput() {
const [uploadFile] = useMutation(UPLOAD_FILE);
return (
<input
type="file"
required
onChange={({target: {validity, files: [file]}}) =>
validity.valid && uploadFile({variables: {file}})
}
/>
);
}
function App() {
return (
<ApolloProvider client={client}>
<div>
<FileInput/>
</div>
</ApolloProvider>
);
}
ReactDOM.render(
<React.StrictMode>
<App/>
</React.StrictMode>,
document.getElementById('root')
);
答案 1 :(得分:1)
此问题可能是由于在初始化服务器时传递可执行模式(schema
选项)而不是较新的API分别传递typeDefs
和resolvers
引起的。
旧:
const server = new ApolloServer({
schema: makeExecutableSchema({ typeDefs, resolvers })
})
新功能:
const server = new ApolloServer({
typeDefs,
resolvers,
})
或如docs中所述:
注意:使用typeDefs时,Apollo Server将
scalar Upload
添加到您的架构中,因此应删除类型定义中所有现有的标量Upload声明。如果您使用makeExecutableSchema创建架构,并使用架构参数将其传递给ApolloServer构造函数,请确保包含scalar Upload
。
答案 2 :(得分:0)
这是我所做的解决方案,添加名为“ FileUpload”的自定义标量,并添加GraphQLUpload作为解析器,如下所示:
import { GraphQLUpload } from 'graphql-upload';
export const resolvers = {
FileUpload: GraphQLUpload
};
效果很好,但是可能不是完美的解决方案。希望阿波罗尽快解决此问题。
P.S。要从浏览器上传文件,您还需要在Apollo Client中正确设置上传链接。这是我的代码:
import { ApolloLink, split } from 'apollo-link';
import { createHttpLink } from 'apollo-link-http';
import { createUploadLink } from 'apollo-upload-client';
// Create HTTP Link
const httpLink = createHttpLink({
uri: ...,
credentials: 'include'
});
// Create File Upload Link
const isFile = value =>
(typeof File !== 'undefined' && value instanceof File) || (typeof Blob !== 'undefined' && value instanceof Blob);
const isUpload = ({ variables }) => Object.values(variables).some(isFile);
const uploadLink = createUploadLink({
uri: ...
credentials: 'include'
});
const terminatingLink = (isUpload, uploadLink, httpLink);
const link = ApolloLink.from([<Some Other Link...>, <Another Other Link...>, terminatingLink]);
const apolloClient = new ApolloClient({
link,
...
});