简体   繁体   中英

(Apollo) GraphQL Merging schema

I am using GraphQL tools/libraries offered by Apollo.

It is possible to merge remote GraphQL schema into a nested structure?

Assume I have n remote schemas, and I would like to merge the Query , Mutation and Subscription from different schemas into a single schema, except, each remote schema is placed under their own type .

Assume we have a remote schema called MenuX with:

type Item {
  id: Int!
  description: String
  cost: Int
}

type Query {
  items: [Item]
}

and a remote schema called MenuY with:

type Item {
  id: Int!
  name: String
  cost: Int
}

type Query {
  items: [Item]
}

I would like to merge the schema into a single schema but under their own types. A contrived example:

type MenuXItem {
  id: Int!
  description: String
  cost: Int
}

type MenuYItem {
  id: Int!
  name: String
  cost: Int
}

type MenuXQuery {
  items: [MenuXItem]
}

type MenuYQuery {
  items: [MenuYItem]
}

type Query {
  MenuX: MenuXItem
  MenuY: MenuYItem
}

As we can see that under the Query type it contains two new types which contain the query type from the remote schemas. Item from schema MenuX have been renamed by using the transformers from graphql-tools , similarly Item from schema MenuY has been transformed as well.

But is it possible to transform the structure as well?

With the actual remote schemas, we are looking at hundreds of types from each schema, and ideally, I would like to not pollute the root types and the Introspection documentation in GraphiQL.

Apollo's graphql-tools includes a module to transform schemas . You should be able to rename everything in MenuX with something like

import {
  makeRemoteExecutableSchema,
  transformSchema,
  RenameTypes
} from 'graphql-tools';
const schema = makeRemoteExecutableSchema(...);
const menuXSchema = transformSchema(schema, [
  RenameTypes((name) => `MenuX${name}`)
]);

Then you can use the transformed schema as the input to mergeSchemas .

Note that the top-level Query and Mutation types are somewhat special and you may want to try to more directly merge those types without renaming them, particularly if they don't conflict.

There is a plugin for Gatsby that contains a transformer that does what you want: https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-graphql/src/transforms.js

It namespaces the types of an existing GraphQL schema, so that you end up with:

type Namespace1Item {
    ...
}

type Namespace2Item {
    ...
}

type Namespace1Query {
    items: [Namespace1Item]
}

type Namespace2Query {
    items: [Namespace2Item]
}

type Query {
    namespace1: Namespace1Query
    namespace2: Namespace2Query
}

So, if you transform your schemas and them merge them, you should be good.

Its possible to achieve schema where Query type has root fields as entry points into source schemas, but only for Query type as Mutation type doesn't support nesting of mutations under names.

For this reason, prefixing names is prefered solution for schema stitching.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM