GraphQL 模式定义语言中的别名类型

ris*_*ott 5 graphql graphql-js apollo-server

我今天在生产中有以下 graphql 模式定义:

type BasketPrice {
  amount: Int!
  currency: String!
}

type BasketItem {
   id: ID!
   price: BasketPrice!
}

type Basket {
   id: ID!
   items: [BasketItem!]!
   total: BasketPrice!
}

type Query {
   basket(id: String!): Basket!
}
Run Code Online (Sandbox Code Playgroud)

我想重命名BasketPrice为 just Price,但是这样做会对架构造成重大更改,因为客户端可能会在片段中引用它,例如

fragment Price on BasketPrice {
   amount
   currency
}

query Basket {
   basket(id: "123") {
      items {
         price {
            ...Price
         }
      }
      total {
         ...Price
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

我曾希望可以为向后兼容起别名,例如

type Price {
  amount: Int!
  currency: String!
}

# Remove after next release.
type alias BasketPrice = Price;

type BasketPrice {
  amount: Int!
  currency: String!
}

type BasketItem {
   id: ID!
   price: BasketPrice!
}

type Basket {
   id: ID!
   items: [BasketItem!]!
   total: BasketPrice!
}

type Query {
   basket(id: String!): Basket!
}
Run Code Online (Sandbox Code Playgroud)

但这似乎不是一个功能。是否有推荐的方法来安全地重命名 graphql 中的类型而不会导致重大更改?

Dan*_*den 0

由于您已经指定的原因,无法在不进行重大更改的情况下重命名类型。重命名类型是一种表面的更改,而不是功能性的更改,因此没有实际理由这样做。

处理架构的任何重大更改的最佳方法是在不同的端点上公开新架构,然后将客户端转换为使用新端点,从而有效地实现 API 的版本控制。

我能想到解决此问题的唯一其他方法是为使用旧类型的任何字段创建新字段,例如:

type BasketItem {
   id: ID!
   price: BasketPrice! @ deprecated(reason: "Use itemPrice instead")
   itemPrice: Price!
}

type Basket {
   id: ID!
   items: [BasketItem!]!
   total: BasketPrice! @ deprecated(reason: "Use basketTotal instead")
   basketTotal: Price!
}
Run Code Online (Sandbox Code Playgroud)

  • 我想重命名该类型的实际原因是其他开发人员可以理解代码。如果命名并不重要,那么我只需调用每种类型 T1、T2、T3 等。我一直认为 gql 相对于 REST 的一个好处是,您不必对 API 进行版本控制,因为您只需添加新的 API字段而不影响使用 @deprecated 字段的客户端,希望类型名称也是如此。 (8认同)
  • 我认为“没有实际理由来重命名事物”是错误的——名称就是文档。名称通常是文档中最重要的部分!这就是为什么“命名事物”是计算机科学中的两个难题之一,这是有很多道理的。 (8认同)