Apollo Federation: Is it possible (and how) to return a concatenated array from different services?

Order Service Schema:

extend type Query {
    order(id: ID!): Order

type Order @key(fields: "id") {
    id: ID!
    notes: [Note]

type Note @key(fields: "id") {
    id: ID!
    title: String!
    body: String!

I have two additional services, Service A and Service B. Is it possible for those services to resolve the order.notes array, and have all of the array values concatenated?

Hello! This pattern as described sounds risky. If multiple subgraphs in your graph can resolve the same entity field (via the @provides directive), they should all resolve that field identically. This is because it isn’t guaranteed which subgraph will resolve that field for any particular query (this is determined at runtime by query-planning logic in the gateway).

Consequently, the logic for each subgraph’s resolver would need to differ slightly to account for pulling in values from the other subgraphs that provide notes. If at all possible, I recommend populating all of a particular list field’s entries from a single subgraph.

Like @StephenBarlow mentioned, this sounds like an anti-pattern. In a scenario like this, I would start by asking “Why do Order Service, Service A, and Service B all need to resolve this field?”. If it’s the data source, then try to consolidate the data-source itself and have one service resolve the field you need.

Take a look at the Concern-based Seperation principle of federation.

In the end, we want the client to work with a schema that has an array of notes at the order level.

It sounds like there are two paths to this:

  1. Keep the schema in its current form, shifting the responsibility of the notes being part of the Order service (not Service A or Service B).
  2. If Service A and Service B truly do need their own notes data, then I’ll have to adjust the schema so that those services expose their own notes array on the hierarchy, then on the client shape the data returned by graphql endpoint to match the final schema (i.e. combine those individual note arrays into one).

We do have a reason for wanting the notes that relate to the service to also be stored and managed within that service. I was just hoping that the query builder had some way, perhaps with a custom directive, that allowed multiple services to provide the contents of an array, then combine them all together before sending down the client. It would save us from having to the data shaping on the client after receiving the graph data.

We will probably take a look again and see if we want to store the notes in its own service and not spread out over the different services.

Perhaps this can be a feature request to enhance the federation service, introduce a federation directive “@concat” or something like that, so that the query plan knows to call each service and concat the results for that field from each service into a single array.