Apollo-Server-Express 没有收到上传对象
Apollo-Server-Express not receiving Upload Object
我正在尝试使用 apollo-server-express 和 apollo-client 上传文件。但是,当文件对象传递给解析器时,它始终为空。我可以在客户端看到文件,但在服务器端看不到。我该如何解决这个问题?
我的架构
type File {
id: ID
path: String
filename: String
mimetype: String
}
extend type Query {
getFiles: [File]
}
extend type Mutation {
uploadSingleFile(file: Upload!): File
}
我的解析器
Mutation: {
uploadSingleFile: combineResolvers(
isAuthenticated,
async (parent, { file }, { models, user, storeUpload }, info) => {
console.log('Resolver-> uploadSingleFile')
console.log(file) // Will return empty, { }
const x = await file
console.log(x) // Will also return empty, { }
const storedFile = storeUpload(file)
return storedFile
}
),
},
我的客户端查询文件
export const UPLOAD_SINGLE_FILE = gql`
mutation uploadSingleFile($file: Upload!) {
uploadSingleFile(file: $file) {
id
}
}
`
我的客户端界面
import React from 'react'
// GQL
import { useApolloClient, useMutation } from '@apollo/react-hooks'
import { UPLOAD_SINGLE_FILE } from '../../queries'
const FileUpload = props => {
const [uploadSingleFile, uploadSingleFileResult] = useMutation(UPLOAD_SINGLE_FILE, {
onCompleted(uploadSingleFile) {
console.log('Completed uploadSingleFile')
}
})
const apolloClient = useApolloClient()
const handleUploadFile = ({
target: {
validity,
files: [file]
}
}) => {
console.log('Uploading file...')
if(validity.valid) {
console.log('Valid')
console.log(file.name)
uploadSingleFile({ variables: { file } })
.then(() => {
apolloClient.resetStore()
})
}
else console.log('Invalid file')
}
return(
<input type="file" required onChange={handleUploadFile} />
)
}
export default FileUpload
已更新
我的前端设置是:
const httpLink = createHttpLink({
uri: 'http://localhost:4000/graphql',
})
const authLink = setContext((_, { headers }) => {
const token = localStorage.getItem('token')
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : "",
}
}
})
const client = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache(),
})
您需要使用 apollo-upload-client
中的适当 Link with your Apollo Client in order to enable file uploads. The easiest way to do that is by using createUploadLink。它可以作为 createHttpLink
的直接替代品,因此只需更换功能即可。
const httpLink = createUploadLink({
uri: 'http://localhost:4000/graphql',
})
const authLink = ...
const client = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache(),
})
假设您已正确设置并使用 link(使用 Daniel 在他的 post 中提到的 createUploadLink),您应该能够一次从 file
中解构道具您在服务器上的解析器中等待承诺。
const { filename, mimetype, createReadStream } = await file.promise;
console.log(filename, mimetype);
// to get a stream to use of the data
const stream = createReadStream();
更新:在较新版本的 graphql-upload 中,您可以像在 OP 中那样等待文件,而不是 file.promise。看来我使用的是旧版本的库。
我正在尝试使用 apollo-server-express 和 apollo-client 上传文件。但是,当文件对象传递给解析器时,它始终为空。我可以在客户端看到文件,但在服务器端看不到。我该如何解决这个问题?
我的架构
type File {
id: ID
path: String
filename: String
mimetype: String
}
extend type Query {
getFiles: [File]
}
extend type Mutation {
uploadSingleFile(file: Upload!): File
}
我的解析器
Mutation: {
uploadSingleFile: combineResolvers(
isAuthenticated,
async (parent, { file }, { models, user, storeUpload }, info) => {
console.log('Resolver-> uploadSingleFile')
console.log(file) // Will return empty, { }
const x = await file
console.log(x) // Will also return empty, { }
const storedFile = storeUpload(file)
return storedFile
}
),
},
我的客户端查询文件
export const UPLOAD_SINGLE_FILE = gql`
mutation uploadSingleFile($file: Upload!) {
uploadSingleFile(file: $file) {
id
}
}
`
我的客户端界面
import React from 'react'
// GQL
import { useApolloClient, useMutation } from '@apollo/react-hooks'
import { UPLOAD_SINGLE_FILE } from '../../queries'
const FileUpload = props => {
const [uploadSingleFile, uploadSingleFileResult] = useMutation(UPLOAD_SINGLE_FILE, {
onCompleted(uploadSingleFile) {
console.log('Completed uploadSingleFile')
}
})
const apolloClient = useApolloClient()
const handleUploadFile = ({
target: {
validity,
files: [file]
}
}) => {
console.log('Uploading file...')
if(validity.valid) {
console.log('Valid')
console.log(file.name)
uploadSingleFile({ variables: { file } })
.then(() => {
apolloClient.resetStore()
})
}
else console.log('Invalid file')
}
return(
<input type="file" required onChange={handleUploadFile} />
)
}
export default FileUpload
已更新
我的前端设置是:
const httpLink = createHttpLink({
uri: 'http://localhost:4000/graphql',
})
const authLink = setContext((_, { headers }) => {
const token = localStorage.getItem('token')
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : "",
}
}
})
const client = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache(),
})
您需要使用 apollo-upload-client
中的适当 Link with your Apollo Client in order to enable file uploads. The easiest way to do that is by using createUploadLink。它可以作为 createHttpLink
的直接替代品,因此只需更换功能即可。
const httpLink = createUploadLink({
uri: 'http://localhost:4000/graphql',
})
const authLink = ...
const client = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache(),
})
假设您已正确设置并使用 link(使用 Daniel 在他的 post 中提到的 createUploadLink),您应该能够一次从 file
中解构道具您在服务器上的解析器中等待承诺。
const { filename, mimetype, createReadStream } = await file.promise;
console.log(filename, mimetype);
// to get a stream to use of the data
const stream = createReadStream();
更新:在较新版本的 graphql-upload 中,您可以像在 OP 中那样等待文件,而不是 file.promise。看来我使用的是旧版本的库。