Tomas Aschan
Tomas Aschan

Reputation: 60664

Schema Stitching in Apollo GraphQL doesn't resolve types from other parts

I'm trying to make my GraphQL schema composable through schema stitching, but I'm struggling with how to resolve properties of types from a different part.

Here's the schema before decomposing:

type Referee {
  id: ID!
  stringProp: String!
}

type Referer {
  id: ID!
  pointer: Referee!
}

type Query {
  referers: [Referer]
}

The types both have resolvers, in their respective schemas, that expand object { id } into { id, stringProp } or { id, pointer: { id } }, so that a query

query FromSingleSchema {
  referers: {
    id
    pointer {
      id
      stringProp
    }
  }
}

resolves as expected; Query.referers resolves to a list of [{id}] objects, and each of those in turn resolve first into a Referer and then fetches the pointed-to Referee through type resolvers.

Now, I try to decompose the schema:

// schema A
type Referee {
  id: ID!
  stringProp: String!
}

// schema B
type Referer {
  id: ID!
}

type Query {
  referers: [Referer]
}

// schema Extensions
extend type Referer {
  pointer: Referee!
}

and compose it again:

// both schemaA and schemaB have been created with makeExecutableSchema
import schemaA from './A'
import schemaB from './B'
// schemaExtensions is just a raw GraphQL string
// resolverExtensions is shown below
import { schemaExtensions, resolverExtensions } from './B'

const schema = mergeSchemas({
  schemas: [schemaA, schemaB, schemaExtensions],
  resolvers: Object.assign({}, resolverExtensions)
})

// resolverExtensions defined as follows:
{
  Referer: {
    pointer: {
      fragment: 'fragment IdFragment on Referee { id }',
      resolve: o => ({ id: o.pointerId })
    }
  }
}

With this, I can run this query without problems:

query OnlyIdFromDecomposedSchemas {
  referers: {
    id
    pointer {
      id
    }
  }
}

but this fails

query FullRefereeFromDecomposedSchemas {
  referers: {
    id
    pointer {
      id
      stringProp
    }
  }
}

with the error message

Cannot return null for non-nullable field Referee.stringProp.

What do I need to do for the type resolver for Referee to be able to fill in the rest of the properties once { id } is available, like it does in a single, non-decomposed, schema?

Upvotes: 0

Views: 1010

Answers (1)

praveenweb
praveenweb

Reputation: 743

I think you are looking for schema delegation. Schema Delegation is a way to automatically forward a query (or a part of a query) from a parent schema to another schema (called a subschema) that is able to execute the query.

You can use delegateToSchema method like this in your resolver:

{
    Referer: {
      pointer : {
        resolve(parent, args, context, info) {
          return info.mergeInfo.delegateToSchema({
            schema: schemaA,
            operation: 'query',
            fieldName: 'referee', // modify according to your query for referee
            context,
            info,
          });
        }
      }
    }
  }

Upvotes: 1

Related Questions