【问题标题】:Connect Apollo with mongodb将 Apollo 与 mongodb 连接起来
【发布时间】:2020-06-13 00:45:18
【问题描述】:

我想将我的 Apollo 服务器与我的 mongoDB 连接起来。我知道那里有很多示例,但我被困在异步部分并且没有找到解决方案或示例(这很奇怪,我完全错了吗?)

我从 next.js https://github.com/zeit/next.js/tree/master/examples/api-routes-apollo-server-and-client 的示例开始。 但是缺少 mongodb 集成。

我的代码

pages/api/graphql.js

    import {ApolloServer} from 'apollo-server-micro';
    import {schema} from '../../apollo/schema';

    const apolloServer = new ApolloServer({schema});

    export const config = {
        api: {
            bodyParser: false
        }
    };

    export default apolloServer.createHandler({path: '/api/graphql'});

apollo/schema.js

    import {makeExecutableSchema} from 'graphql-tools';
    import {typeDefs} from './type-defs';
    import {resolvers} from './resolvers';

    export const schema = makeExecutableSchema({
        typeDefs,
        resolvers
    });

apollo/resolvers.js

    const Items = require('./connector').Items;
    export const resolvers = {
        Query: {
            item: async (_parent, args) => {
                const {id} = args;
                const item = await Items.findOne(objectId(id));
                return item;
            },
            ...
        }
    }

apollo/connector.js

    require('dotenv').config();
    const MongoClient = require('mongodb').MongoClient;

    const password = process.env.MONGO_PASSWORD;
    const username = process.env.MONGO_USER;
    const uri = `mongodb+srv://${username}:${password}@example.com`;

    const client = await MongoClient.connect(uri);
    const db = await client.db('databaseName')
    const Items = db.collection('items')

    module.exports = {Items}

所以问题是connector.js 中的await。我不知道如何在异步函数中调用它,或者如何以其他方式将 MongoClient 提供给解析器。如果我只是删除await,它显然会返回一个待处理的承诺,并且不能在其上调用函数.db('databaseName')

【问题讨论】:

    标签: mongodb async-await graphql apollo next.js


    【解决方案1】:

    不幸的是,我们距离拥有top-level await 仍有一段距离。

    您可以延迟运行其余代码,直到 Promise 解决,方法是将其放在 Promise 的 then 回调中。

    async function getDb () {
      const client = await MongoClient.connect(uri)
      return client.db('databaseName')
    }
    
    getDb()
      .then(db => {
        const apollo = new ApolloServer({
          schema,
          context: { db },
        })
        apollo.listen()
      })
      .catch(e => {
        // handle any errors
      })
    

    或者,您可以在第一次需要时创建连接并缓存它:

    let db
    
    const apollo = new ApolloServer({
      schema,
      context: async () => {
        if (!db) {
          try {
            const client = await MongoClient.connect(uri)
            db = await client.db('databaseName')
          catch (e) {
            // handle any errors
          }
        }
        return { db }
      },
    })
    apollo.listen()
    

    【讨论】:

    • 谢谢!第二个例子做到了!第一个在 next.js 的 page/api 文件夹中是不可能的。因为我必须以同步的方式导出 ApolloServer 并且不能等待 DB 在第一步中连接。但是第二个非常好并且有效?
    • 第一种模式仍然有效,但您可能需要更改文件结构。
    猜你喜欢
    • 2019-02-22
    • 2020-05-12
    • 2020-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-01
    • 2018-02-22
    • 2020-08-13
    相关资源
    最近更新 更多