2

I'm running a gateway with apollo-server v2 with graphql-tools v7 and have the following services and subschemas, which I've set up as a (contrived) proof-of-concept:

Service 1:

Query {
  getUser(input: GetUserInput!): User
}

input GetUserInput {
  id: ID!
}

type User {
  id: ID!
  contacts: Contacts
}

type Contacts {
  id: ID!
  primary: String
}

Service 2:

Query {
  getUser(input: GetUserInput!): User
}

input GetUserInput {
  id: ID!
}

type User {
  id: ID!
  contacts: Contacts
}

type Contacts {
  id: ID!
  secondary: String
}

The gateway has the combined schema like this:

Query {
  getUser(input: GetUserInput!): User
}

input GetUserInput {
  id: ID!
}

type User {
  id: ID!
  contacts: Contacts
}

type Contacts {
  id: ID!
  primary: String
  secondary: String
}

The gateway is configured to stitch the schemas and merge the User type like this:

import { stitchSchemas } from "@graphql-tools/stitch"
...
const schema = stitchSchemas({
  subschemas: [
    {
      schema: service1Schema,
      executor: service1Executor,
      merge: {
        User: {
          fieldName: "getUser",
          selectionSet: "{ id }",
          args: (originalObject) => ({
            input: {
              id: originalObject.id
            }
          }),
        },
      }
    },
    {
      schema: service2Schema,
      executor: service2Executor,
      merge: {
        User: {
          fieldName: "getUser",
          selectionSet: "{ id }",
          args: (originalObject) => ({
            input: {
              id: originalObject.id
            }
          }),
        },
      }
    },
  ]
})

However, when I send a query to fetch the contacts field for a User, only Service 2 is called by the gateway. Instead, I would have expected the gateway to call Service 1 to get its representation of User.contacts and also Service 2 to get its representation of User.contacts and then merge the two into a combined result.

The query I executed:

query GetContacts {
  getUser(input: { id: "123" }) {
    contacts {
      primary
      secondary
    }
  }
}

The result I got (and I see in logs that Service 1 was not called at all):

{
  "data": {
    "getUser": {
      "contacts": {
        "primary": null,
        "secondary": "Secondary contact from Service 2"
      }
    }
  }
}

The result I expected:

{
  "data": {
    "getUser": {
      "contacts": {
        "primary": "Primary contact from Service 1",  <-- This should be included in the result.
        "secondary": "Secondary contact from Service 2"
      }
    }
  }
}

I have confirmed that I'm able to fetch other fields (e.g. User.name) from Service 1 successfully, so the subschema for Service 1 is configured correctly on the gateway (though probably not the merge options for it).

Since this is similar to the example from the graphql-tools documentation, I'm confused about why the fields of the Contacts type aren't merged as expected in the query response.

Michel Floyd
  • 18,793
  • 4
  • 24
  • 39

0 Answers0