Prisma GraphQL 模式和数据模型之间的同一字段可以有不同的类型吗?

Posted

技术标签:

【中文标题】Prisma GraphQL 模式和数据模型之间的同一字段可以有不同的类型吗?【英文标题】:Can one have different types for same field between Prisma GraphQL schema and datamodel? 【发布时间】:2019-09-21 00:54:59 【问题描述】:

我是 Prisma/GraphQL 的新手。我正在编写一个简单的 ToDo 应用程序并使用 Apollo Server 2 和 Prisma GraphQL 作为后端。我想将我的 createdAt 字段从数据模型转换为前端更有用的东西,比如 UTC 日期字符串。我的想法是转换存储的值,即 DateTime。

我的datamodel.prisma 具有以下 ToDo 类型

type ToDo 
id: ID! @id
added: DateTime! @createdAt
body: String!
title: String
user: User!
completed: Boolean! @default(value: false)


added 字段是一个 DataTime。但在我的schema.js 中,我将该字段列为字符串

 type ToDo 
    id: ID!
    title: String,
    added: String!
    body: String!
    user: User!
    completed: Boolean!

  

然后我在我的解析器中转换它

 ToDo: 
    added: async (parent, args) => 
      const d = new Date(parent.added)
      return d.toUTCString()
    

这样可以吗?也就是说,datamodelschema 中的同一字段有不同的类型?它似乎工作正常,但我不知道在其他情况下遵循这种技术是否会让自己在路上遇到麻烦。

如果是这样,我很好奇的一件事是为什么在 ToDo.added 解析器中访问 parent.added 不会启动某种“无限循环”——也就是说,当您访问 parent.added 字段时它不需要解析器来解析该字段,它访问parent.added 字段,依此类推。 (我想它足够聪明,不会那样做?)

【问题讨论】:

【参考方案1】:

我对 Prisma 的经验有限,但我知道您可以将其视为您自己的 GraphQL 服务器和数据(即数据库)之间的额外后端 GraphQL 层接口。

您的第一个模型 (datamodel.prisma) 使用增强的 Prisma 语法和指令来准确描述您的数据,并由 Prisma 层使用,而第二个模型使用标准 GraphQL 语法来实现与有效的标准 GraphQL 相同的对象类型,并由您自己的后端使用。

实际上,如果您查看它,您会发现 Prisma 使用的 DateTime 类型实际上是 String,但 Prisma 很可能使用它来验证日期和时间格式等,所以有两种模型之间没有根本差异。但即使存在差异,这也取决于您,因为您可以使用解析器覆盖从 Prisma 获得的数据,然后再从您自己的后端返回。

简而言之,我在这里想说的是,您正在处理 2 个不同的 GraphQL 层:Prisma 和您自己的。虽然 Prisma 的作用是准确地表示数据库中存在的数据,并为您提供广泛的 CRUD 方法来处理该数据,但您自己的层可以(并且应该)根据您的特定需求进行定制。

至于您的解析器问题,parent 在此上下文中将保存父解析器返回的对象。假设您在根Query 级别有一个getTodo 查询,返回一个ToDo 类型的项目。假设您将此解决为 Prisma 检索单个 ToDo 的默认操作。根据您的datamodel.prisma 文件,此查询将解析为具有added 属性的对象(它将作为createdAt 字段存在于您的数据库中,由@createdAt Prisma 指令指定)。所以parent.added 将保留该值。

您的 added 解析器所做的是将原始数据转换为实际的 Date 对象,然后将其格式化为 UTC 字符串,该字符串符合您的 schema.js 文件,其中 added 字段是输入String!

【讨论】:

以上是关于Prisma GraphQL 模式和数据模型之间的同一字段可以有不同的类型吗?的主要内容,如果未能解决你的问题,请参考以下文章

GraphQL 和 Prisma:当它们已经是 Prisma 数据库模式的一部分时,为啥要在应用程序模式中重新定义类型?

GraphQL/Prisma 订阅仅针对 DELETE 触发

模式拼接两个远程 Prisma/GraphQL 模式

Prisma、GraphQL 和 Apollo 中具有突变的数据关系和连接类型

在单个解析器中一次创建两种类型的数据 (Graphql + Prisma)

使用 Prisma 和 Apollo 调用多个 GraphQL 突变的正确方法是啥