在多种类型上使用GraphQL Fragment

Goo*_*dea 13 apollo graphql

如果我的GraphQL架构中有多个类型共有的字段集,有没有办法做这样的事情?

type Address {
  line1: String
  city: String
  state: String 
  zip: String
}

fragment NameAndAddress on Person, Business {
  name: String
  address: Address
}

type Business {
   ...NameAndAddress
   hours: String
}

type Customer {
   ...NameAndAddress
   customerSince: Date
}
Run Code Online (Sandbox Code Playgroud)

Dan*_*den 8

片段仅在发出请求时在客户端使用 - 它们不能在架构中使用.GraphQL不支持类型继承或任何其他机制,可以减少必须为不同类型写出相同字段的冗余.

如果您正在使用apollo-server,构成架构的类型定义只是一个字符串,因此您可以通过模板文字实现您正在寻找的功能:

const nameAndAddress = `
  name: String
  address: Address
`

const typeDefs = `
  type Business {
     ${nameAndAddress}
     hours: String
  }

  type Customer {
     ${nameAndAddress}
     customerSince: Date
  }
`
Run Code Online (Sandbox Code Playgroud)

或者,有些库,如graphql-s2s,允许您使用类型继承.

  • 我觉得很奇怪,GraphQL不支持这一点.情况是类型及其相应的输入有很多共享字段.使用字符串插值意味着我不能只使用简单的`.graphql`文件.它还意味着另一种语言不能使用相同的`.graphql`文件.在GraphQL中应该真的支持这样的事情. (5认同)

Fla*_*ken 5

您可以,但 GraphQL 不会让您在两种类型之间创建片段,除非您在架构中指定这些类型共享相同的属性。为此,您必须使用接口。然后,您将能够在客户端构建此界面的片段。

服务器端架构:


interface NameAndAddress {
  name: String
  address: Address
}


type Address {
  line1: String
  city: String
  state: String 
  zip: String
}

type Business implements NameAndAddress {
  # by design you have to write those properties again
  name: String
  address: Address

  hours: String
}

type Customer implements NameAndAddress {
  name: String
  address: Address

  customerSince: Date
}
Run Code Online (Sandbox Code Playgroud)

然后在你的客户端

# define a fragment on the interface
fragment NameAndAddress on NameAndAddress {
  name: String
  address: Address
}

# you can then get the fields as follow
query {
  business {
     ...NameAndAddress
  }

  customer {
     ...NameAndAddress
  }
}

Run Code Online (Sandbox Code Playgroud)