【发布时间】:2023-03-16 18:15:01
【问题描述】:
首先要说我看到了这个问题Sharing a pg-promise task across parts of an http request并阅读了答案。我想重新审视这个问题,增加一些复杂性。
我正在使用 postgres 数据库作为后端,pg-promise 作为数据库接口库,在 apollo-server-express 上开发 typescript graphql 服务器。我有使用数据加载器的查询解析器,使用此处描述的模式:https://github.com/graphql/dataloader#creating-a-new-dataloader-per-request。
所有数据库访问都通过pg-promise 的单个实例进行,如推荐的那样,例如https://github.com/vitaly-t/pg-promise-demo/blob/master/TypeScript/db/index.ts.
与最初的问题一样,我正在尝试找到一种创建任务的好方法,该任务可以合并到数据加载器中(或在调用数据加载器时作为参数传递),以便查询解析器在单个数据库连接中运行。我不知道将调用哪些解析器或调用它们的顺序,所以我不能说某个解析器应该创建任务。
我一直在尝试找到一种方法来使用 graphql Context 来共享任务,因为我目前正在使用 Context 来共享 dataloaders 对象,但如前所述,任务中的所有调用都发生在一个回调函数,因此通过Context 共享任务已结束。以下是如何设置上下文的示例:
/*
createLoaders() returns a new object of DataLoaders e.g.
{
users: new DataLoader(ids => getUsers(ids)),
tags: new DataLoader(ids => getTags(ids))
}
*/
import { createLoaders } from './dataloaders'
const server = new ApolloServer({
schema,
context: (): Promise<Context> => {
// create a connection here to inject into createLoaders?
const loaders = createLoaders()
return { loaders }
}
})
以及 Apollo 文档中在上下文中创建数据库连接的示例:https://www.apollographql.com/docs/apollo-server/data/resolvers/#the-context-argument(请注意,它们没有描述在任何地方关闭连接)。
context: async () => ({
db: await client.connect(),
})
// Resolver
(parent, args, context, info) => {
return context.db.query('SELECT * FROM table_name');
}
如果不使用connect 方法,这可能是不可能的,但是库的作者不鼓励将其用于这种类型的操作。同样的问题是,在将结果发送回客户端之前最终解决查询时,需要将连接返回到池中。
感谢任何帮助! (感谢@vitaly-t 在pg-promise 上的出色工作)
编辑 1 @Daniel-Rearden 你的建议和链接的要点最终奏效了。如果总是打开任务成为问题,我可能会检查来自插件内的传入请求。标记你的答案正确!
【问题讨论】:
标签: typescript graphql apollo-server pg-promise dataloader