简而言之,此解析器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 })
}
那不起作用,看了之后,为什么会这样呢?子解析器从父对象获取数据,在这种情况下是每个文章。
答案 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连接中的某些值是函数。地图能够处理。对象不是。您可能会看到与子解析器中的数据库连接相关的非常模糊的爆炸,除非您传递地图。