2017-09-04 54 views
0

总之,该解析器getAllArticles()返回物品系列,并且每篇文章都有一个作者字段和标签领域,使每篇文章能发射子分解器来获取这些数据,但我无法查看和找到最佳解决方案。如何通过DB连接到子解析器当根解析器返回一个迭代

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

app.js

我传递的DB连接到顶级解析器为根值的地图。

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

我通过分配它们到响应对象传递分贝连接到子解析器。

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()解析器返回文章数组。我看不到如何附上地图。

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 }) 
} 

这并不工作,并看着它,为什么会之后?子分解器从父对象获取数据,这是本例中的每篇文章。

回答

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上下文参数中,只要确保您传入包含数据库连接的映射而不是对象。 DB连接中的某些值是函数。地图能够处理。对象不是。除非你传递一个Map,否则你可能会在你的子解析器中看到与DB连接有关的可怕的模糊引爆。

+1

你可以只通过该数据库连接到你的背景下,而不是利用根值。这将使所有你的解析器都可用,而无需额外的工作。 –

+0

你知道,现在我听到你说了,我想我记得一些来自Apollo Server的文档,他说这样做建议不要将它传递给根值。我会尽力找到它。谢谢。 – agm1984

+0

我什么都看不到,但是这个页面是我在想的地方:http://dev.apollodata。com/tools/apollo-server/setup.html。我很肯定你是发现的,因为我知道我已经阅读过指出这一点的文档,在那些日子里,我阅读了数百篇关于GraphQL的文章:)我认为Jonas Helfer或Lee Byron明确地说过它。我想,使用'context'将会是一个相当直接的改进。我会用结果更新我的帖子。 – agm1984