我应该如何确定查询返回到 GraphQL 接口类型的显式类型?

Posted

技术标签:

【中文标题】我应该如何确定查询返回到 GraphQL 接口类型的显式类型?【英文标题】:How should I determine the explicit type returned by a query to a GraphQL interface type? 【发布时间】:2020-05-24 04:53:37 【问题描述】:

假设我们有这个使用继承的 GraphQL 模式:

Query 
  maintenanceEvents: [MaintenanceEvent]!


interface MaintenaceEvent 
  time: DateTime


type OilChange implements MaintenanceEvent 
  time: DateTime
  oilType: OilType


type TireRotation implements MaintenanceEvent 
  time: DateTime
  pattern: RotationPattern


... more types

假设客户端将显示时间轴上发生的事件类型的摘要。问题是(据我所知)客户端没有直接的方法来确定它从服务器接收的数组中每个事件的类型。

我想出的一些选项:

    向接口和实现它的每个类型添加一个“类型”字段。

    看起来像这样:

    enum MaintenanceEventType 
      OIL_CHANGE
      TIRE_ROTATION
      ... more types
    
    
    interface MaintenanceEvent 
      time: DateTime
      type: MaintenanceEventType
    
    
    type OilChange implements MaintenanceEvent 
      time: DateTime
      type: MaintenanceEventType
      oilType: OilType
    
    
    ...etc.
    

    这是我想出的最佳选择,但也有一些我不喜欢的地方。有两个维护事件类型列表要保持同步:枚举和接口集。此外,为给定类型发送一个始终相同的字段似乎是多余的。

    根据存在的字段确定前端的类型。

    这不是一个好的选择。如果将字段添加到类型中,那么它很容易出错,并且确定哪种类型的逻辑会发生变化。此外,它不能处理实现接口但没有附加字段的类型。

是否有一个既定的模式,或者处理这个的 GraphQL 规范的一部分?这不是 GraphQL 接口的好应用吗?

【问题讨论】:

【参考方案1】:

您应该使用__typename 字段。来自spec:

GraphQL 支持通过元字段 __typename:String!查询任何对象、接口或联合时。它返回当前正在查询的对象类型的名称。

这最常用于查询接口或联合类型以确定返回的可能类型的实际类型。

此字段是隐式的,不会出现在任何已定义类型的字段列表中。

您的查询将类似于:

query 
  maintenanceEvents 
    __typename
    time
    ... on OilChange 
      oilType
    
    ... on TireRotation 
      pattern
    
  

请注意,如果您使用 Apollo 客户端,__typename 字段将自动添加到您的查询中 - 在这种情况下无需自己显式添加。

【讨论】:

以上是关于我应该如何确定查询返回到 GraphQL 接口类型的显式类型?的主要内容,如果未能解决你的问题,请参考以下文章

graphql 查询或突变能否返回标量值

GraphQL Node.js:确定查询中使用的类型

如何从 MySQL 查询中将 json 返回到 GraphQL?

当graphQL的查询从mongodb返回空数据时,你应该检查啥?

GraphQL:如何实现 GraphQLObjectTypes 的 GraphQLList

使用 MongoDB 时的 Graphql 接口