最好将 prisma 对象通过上下文传递给解析器还是直接使用它?

Posted

技术标签:

【中文标题】最好将 prisma 对象通过上下文传递给解析器还是直接使用它?【英文标题】:Is better pass prisma object through context to resolvers or use it directly? 【发布时间】:2019-08-29 12:24:56 【问题描述】:

我想知道直接在解析器中使用 prisma 客户端或通过上下文传递它是否更好或有什么不同。

在官方文档中是通过上下文传递的:

const  prisma  = require('./generated/prisma-client');

const resolvers = 
  Query: 
    feed: (parent, args, context) => 
      return context.prisma.posts( where:  published: true  )
    


const server = new GraphQLServer(
  typeDefs: './src/schema.graphql',
  resolvers,
  context: 
    prisma,
  ,
)

我的问题是:为什么不直接在解析器中使用 prisma 客户端。

const  prisma  = require('./generated/prisma-client');

const resolvers = 
  Query: 
    feed: (parent, args, context) => 
      return prisma.posts( where:  published: true  )
    


const server = new GraphQLServer(
  typeDefs: './src/schema.graphql',
  resolvers,
)

这个解决方案有什么问题吗?

【问题讨论】:

【参考方案1】:

尽管您的方法没有任何问题,但您希望通过上下文来执行此操作有几个原因:

    当您将编写单元测试时,您可以轻松地将 prisma 替换为模拟实现。这是一个例子:https://github.com/javascript-af/javascript-af/blob/1e89e5436fbf0d6e3de37f12e6853a8ff6fc7898/packages/backend/tests/utils/gqlTestClient.ts#L12

    您可以通过这种方式轻松传递两个 prisma 实例,就像您想在其他地方查询数据一样。您可以通过使用两个单独的端点实例化 Prisma 类并通过上下文对象中的两个键将其传递给 graphql 服务器来传递 context.db1context.db2

    在 graphql 文档中,建议通过上下文传递 DB 访问。遵循规范总是好的:https://graphql.org/learn/execution/#asynchronous-resolvers

【讨论】:

此外,您可以根据请求创建上下文,从而在多租户架构中动态使用 prisma 实例或其他实例(请参阅prisma-multi-tenant) 但是通过上下文传递它时如何获得工作强度。 上下文总是变得一团糟,并鼓励大量的反模式。随着时间的推移,你最终会得到很多垃圾,比如“这个变量是否存在于上下文对象上?”,并且实现细节到处泄漏。我刚刚开始使用图形/棱镜,但我真的很想找到一种更好的方法......【参考方案2】:

您不希望解析器访问您的完整架构,这是不必要的风险。

【讨论】:

以上是关于最好将 prisma 对象通过上下文传递给解析器还是直接使用它?的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI - 将托管对象上下文传递给模型

如何将上下文对象传递给 NSValueTransformer

如何将对象上下文传递给 jQuery.ajax JSONP 回调?

将上下文传递给许多方法是否正常?

通过 HOC 将 React 上下文传递给包装的组件

如何将参数传递给 GraphQL 中的子属性