简而言之,此解析器getAllArticles()
返回一系列文章,每篇文章都有一个作者字段和标签字段,因此每篇文章都可以触发该数据以获取该数据,但是我很难看到并找到最佳的解决方案。
您必须知道一些背景故事:
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
我通过将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 })
}
那不起作用,看了看它,为什么呢?子底物从父对象中获取数据,这是在这种情况下的每个文章。
经过一些迭代后,这是可行的解决方案:
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驱动程序连接到解析器的方法。它收紧了整体架构,使我可以轻松旋转其他解析器,因为它们配有包括电池。
如果将DB连接传递到GraphQl上下文参数中,只需确保将包含DB连接的地图传递到映射,而不是对象。数据库连接中的某些值是函数。地图能够处理它。对象不是。您可能会看到与子交水器中的DB连接有关的可怕的爆炸,除非您绕过地图。