当根解析器返回可迭代的

时间:2017-09-04 20:34:07

标签: node.js graphql iterable resolver

简而言之,此解析器getAllArticles()返回一个文章数组,每篇文章都有一个作者字段和一个标签字段,因此每篇文章都可以触发子解析器来获取该数据,但我遇到了麻烦看到并找到最佳解决方案。

你必须知道一些背景故事:

app.js

我将数据库连接作为根值中的映射传递给顶级解析器。

const db = new Map()
db.set('Neo4J', Neo4J.getDriver())
db.set('MongoDB', MongoDB.getDB())

// GraphQL Endpoint
app.use('/graphql', bodyParser.json(), graphqlExpress((req) => {
    // ...
    return {
        schema,
        context,
        rootValue: {
            db
        }
    }
}))

getArticle.js

我将db连接传递给子解析器,方法是将它们分配给响应对象。

const getArticle = async (root, args, context) => {
    const db = root.db
    const Neo4J = db.get('Neo4J')
    const MongoDB = db.get('MongoDB')
    // ...
    const article = { /* ... */ }
    return Object.assign({}, article , { db })
}

这很好用(代码变得非常干净),直到我转移到返回一系列文章的getAllArticles()解析器。我看不到如何附加db地图。

getAllArticles.js

以下是直接添加的内容:

const getAllArticles = async (root, args, context) => {
    const db = root.db
    const Neo4J = db.get('Neo4J')
    const MongoDB = db.get('MongoDB')
    // ...
    const articles = [{ /* ... */ }, { /* ... */ }, { /* ... */ }]
    return Object.assign({}, articles, { db })
}

那不起作用,看了之后,为什么会这样呢?子解析器从父对象获取数据,在这种情况下是每个文章。

1 个答案:

答案 0 :(得分:0)

经过一些迭代,这是可行的解决方案:

<强> app.js

import Neo4J from './connectors/neo4j'
import MongoDB from './connectors/mongodb'
const db = new Map([
    ['Neo4J', Neo4J.getDriver()],
    ['MongoDB', MongoDB.getDB()]
])

app.use('/graphql', bodyParser.json(), graphqlExpress((req) => {
    const context = {
        settings: { SECRET },
        person: req.person,
        db
    }
    return {
        schema,
        context,
        rootValue: null
    }
}))

<强> everyResolver.js

const getSomething = async (root, args, context, info) => {
    const db = context.db
    const Neo4J = db.get('Neo4J')
    const MongoDB = db.get('MongoDB')

    const session = Neo4J.session()
    session.run(query) // etc

    const users = MongoDB.collection('users')
    users.findOne(ObjectID(id)) // etc

    return objectOrIterable
}

希望这可以在将来帮助其他人。我非常喜欢将DB驱动程序连接传递给解析器的方法。它收紧了整体架构并允许我轻松地旋转其他旋转变压器,因为它们带有电池。

  

如果将数据库连接传递给GraphQL上下文参数,只需确保传入包含数据库连接的Map,而不是Object。 DB连接中的某些值是函数。地图能够处理。对象不是。您可能会看到与子解析器中的数据库连接相关的非常模糊的爆炸,除非您传递地图。