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?