【发布时间】:2020-12-01 14:55:37
【问题描述】:
我想通过 Apollo 突变将文件上传到 mongodb 数据库。 这是我的一些配置: server.js(这里是 4000 端口):
...
// Connect to Mongo
mongoose
.connect(process.env.mongoURI, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
useFindAndModify: false
}) // Adding new mongo url parser
.then(() => console.log('MongoDB Connected...'))
.catch(err => console.log(err));
const { ApolloServer } = require('apollo-server-express');
const typeDefs = require('./modules/graphqlschemas/index');
const resolvers = require('./modules/resolvers/index');
// #5 Initialize an Apollo server
const server = new ApolloServer({
typeDefs: typeDefs,
resolvers: resolvers,
context: ({ req }) => ({
getUser: () => req.user,
logout: () => {
req.session = null;
req.logout();
return true
}
})
});
...
现在我的架构和解析器:
graphqlschemas/image.js
module.exports = `
type File {
_id: ID!
path: String!
filename: String!
mimetype: String!
encoding: String!
},
type Query {
uploads: [File]
},
type Mutation {
singleUpload(file: Upload!): File!
}
`;
resolvers/image.js(这是我观察到的非常重要的事情,那里的文件始终为空)
const Image = require('../../models/image');
module.exports = {
Query: {
uploads: (parent, args) => Image.find({}),
},
Mutation: {
singleUpload: async (parent, {file}) => {
console.log(file); // always null
}
}
}
,但让我们进一步了解客户端(React 应用程序在端口 3000 上):
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import { ApolloProvider } from '@apollo/react-hooks';
import ApolloClient from "apollo-boost";
import { InMemoryCache } from 'apollo-cache-inmemory';
import { createUploadLink } from 'apollo-upload-client';
import { onError } from "apollo-link-error";
import { ApolloLink } from "apollo-link";
// const link = createUploadLink({ uri: '/graphql' });
const client = new ApolloClient({
link: ApolloLink.from([
// Report errors to console in a user friendly format
onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors)
graphQLErrors.map(({ message, locations, path }) =>
console.log(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
)
);
if (networkError) console.log(`[Network error]: ${networkError}`);
}),
createUploadLink({
uri: '/graphql'
})
]),
cache: new InMemoryCache()
});
ReactDOM.render(
<ApolloProvider client={client}>
<App />
</ApolloProvider>,
document.getElementById('root')
);
serviceWorker.unregister();
突变查询(我正在使用codgen生成graphql hooks):
mutation SingleUpload($file: Upload!) {
singleUpload(file: $file) {
_id
filename
}
}
以及使用组件上传文件(最重要的行):
const [fileData, setFileData] = useState(null);
const [singleUpload] = useSingleUploadMutation();
const onChangeFile = e => {
setFileData(e.target.files[0]);
};
console.log(fileData);
const onChangeText = e => {
setNewsData({
...newsData,
[e.target.name]: e.target.value
});
}
const onSubmit = async e => {
e.preventDefault();
await singleUpload({ variables: { file: fileData } });
}
return (
<form id="addNews" onSubmit={onSubmit}>
<div className="form-group">
<input id="news" type="file" name="news" placeholder="Add photo" onChange={onChangeFile} />
</div>
<div className="form-group mt-4 mb-0">
<input type="submit" className="btn btn-primary btn-block" value="Add photo"/>
</div>
</form>
)
,但是在解析器中等于null,所以也许这就是问题所在?
【问题讨论】:
-
不清楚你为什么用
variables包装。await singleUpload({ variables: { file: fileData } });。我认为一个简单的调试检查是稍微改变你的解析器而不破坏参数并将其注销。singleUpload: async (parent, logThisArg) => { -
我这样做了很多次。它给了我:文件:{}
-
单独服务器上传作品?用邮递员测试 - 多部分/表格?邮递员测试后 - 检查反应请求正文是否相同/详细比较它们
标签: javascript mongodb file-upload graphql apollo