Suppose you have two separate GraphQL APIs, each with its own schema: products
and reviews
. The products
API has a Product
type, and the reviews
API has a Review
type. You want to create a unified GraphQL API that includes both types, so that clients can query for products and their associated reviews in a single request.
To do this, you can use schema stitching. Here's an example:
First, you define the schema for each API. Here's an example for the products
API:
type Product { id: ID! name: String! price: Float! }
And here's an example for the reviews
API:
type Review { id: ID! productId: ID! rating: Int! comment: String! }
Next, you define resolvers for each API. These resolvers will be used to fetch data from the underlying data sources. Here's an example for the products
API:
const products = [ { id: '1', name: 'Product 1', price: 10.0 }, { id: '2', name: 'Product 2', price: 20.0 }, { id: '3', name: 'Product 3', price: 30.0 }, ]; const productResolver = { Query: { product: (_, { id }) => products.find(p => p.id === id), }, };
And here's an example for the reviews
API:
const reviews = [ { id: '1', productId: '1', rating: 5, comment: 'Great product!' }, { id: '2', productId: '1', rating: 4, comment: 'Good product.' }, { id: '3', productId: '2', rating: 3, comment: 'Okay product.' }, { id: '4', productId: '3', rating: 2, comment: 'Not so great.' }, ]; const reviewResolver = { Query: { review: (_, { id }) => reviews.find(r => r.id === id), reviewsForProduct: (_, { productId }) => reviews.filter(r => r.productId === productId), }, };
Now you can stitch the schemas together using the makeExecutableSchema
function from the graphql-tools
package. Here's an example:
const { makeExecutableSchema } = require('graphql-tools'); const productSchema = ` type Product { id: ID! name: String! price: Float! reviews: [Review] } type Query { product(id: ID!): Product } `; const reviewSchema = ` type Review { id: ID! productId: ID! rating: Int! comment: String! } type Query { review(id: ID!): Review reviewsForProduct(productId: ID!): [Review] } `; const schema = makeExecutableSchema({ typeDefs: [productSchema, reviewSchema], resolvers: [productResolver, reviewResolver], }); module.exports = schema;
The makeExecutableSchema
function takes an array of type definitions and an array of resolver functions, and returns a single schema that includes both types. In this example, we're defining a new Product
type that includes a list of Review
objects.