Skip to content

How to stitch from a concrete to an abstract type? #751

@josephktcheung

Description

@josephktcheung

Hi,

Not sure if it's asked before. I'm currently stitching 2 graphql schemas together but I'm not sure how can I transform a node interface query result to a concrete type.

Here's a modified apollo stitching example. https://launchpad.graphql.com/0vjzzp49r5

Let's say both Chirp and Author implement Node interface. Instead of providing chirpById and authorById, both schemas only provide node query to query any item that implements Node interface.

import {
  makeExecutableSchema,
  addMockFunctionsToSchema,
  mergeSchemas,
} from 'graphql-tools';

// Mocked chirp schema
// We don't worry about the schema implementation right now since we're just
// demonstrating schema stitching.
const chirpSchema = makeExecutableSchema({
  typeDefs: `
    type Chirp {
      id: ID!
      text: String
      authorId: ID!
    }

    type Query {
      node(id: ID!): Node
      chirpsByAuthorId(authorId: ID!): [Chirp]
    }
  `
});

addMockFunctionsToSchema({ schema: chirpSchema });

// Mocked author schema
const authorSchema = makeExecutableSchema({
  typeDefs: `
    type User implements Node {
      id: ID!
      email: String
    }

    type Query {
      node(id: ID!): Node
    }
  `
});

addMockFunctionsToSchema({ schema: authorSchema });

export const schema = mergeSchemas({
  schemas: [
    chirpSchema,
    authorSchema,
  ],
});

And again we want to extend both Chirp and Author type:

const linkTypeDefs = `
  extend type User {
    chirps: [Chirp]
  }

  extend type Chirp {
    author: User
  }
`;

Then in the resolver map, here's how I resolve Chirp's author field by querying the node query from the Author schema...

{
  ...
    Chirp: {
      author: {
        fragment: `fragment ChirpFragment on Chirp { authorId }`,
        resolve(chirp, args, context, info) {
          return info.mergeInfo.delegateToSchema({
            schema: authorSchema,
            operation: 'query',
            fieldName: 'node',
            args: {
              id: chirp.authorId,
            },
            context,
            info,
          });
        },
      },
    },
}

Now if I perform the following query on the stitched schema, the author's email returns null:

query NotWorking {
  node(id: "fakeUserId") {
    ... on User {
      chirps {
        id
        author {
          email
        }
      }
    }
  }
}

I can get the author's email by doing something like this but it's not desirable:

query KindOfWorking {
  node(id: "fakeUserId") {
    ... on User {
      chirps {
        id
        author {
          ... on User {
            email
          }
        }
      }
    }
  }
}

Is it possible to make NotWorking query works i.e. getting User's fields without using inline fragments? Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions