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。看来我使用的是旧版本的库。