Recommended pattern for orchestrating multiple entities and computed fields

I can’t find much discussion on the internet for how this might be achieved, help would be appreciated.

Let’s start with a basic example:

# Data1
type Data1 @key(fields: "id") {
  id: ID!
  someData: String!
}

# Another service, separate from Data1 service, stubs omitted
type Data1 @key(fields: "id"){
  id: ID!
  someData: String! @external
  serviceOneData: String! @requires(fields: "someData")
}

Above is classico federation. It works because the service is contributing to the Data1 entity in a semantically meaningful way. I’m having a difficult time understanding how to compose multiple entities for a computed field. For example, what if I need to create an entity that has a field that depends on some data from a new Data2 entity?

From what I’ve observed, it seems like one option is to compose these throughout the subgraphs, like so:

# Data1 
type CompositeType @key(fields: "id") {
  id: ID!
  data1: Data1!
}

# Data2
type CompositeType @key(fields: "id") {
  id: ID!
  data2: Data2!
}

# some other service, stubs omitted
type CompositeType @key(fields: "id") {
  id: ID!
  data1: Data1! @external
  data2: Data2! @external
  compositeField: String! @requires(fields: "data1{ someData } data2{ someData }")
}

While this works, I don’t like it at all. Primarily because it doesn’t seem very flexible: each subgraph needs to be aware of all possible composite types.

Are there better ways to achieve this?

Hello :waving_hand:
Your suggestion to compose those throughout the subgraphs (i.e. having a field that @requires multiple fields that may come from multiple subgraphs) is currently the only way to achieve that.

By explicitly requiring all those external types to be defined in your subgraphs (your data1 and data2 fields should be @external) you are explicitly specifying the intent that you want to depend on this type of data and libraries can validate those locally.