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:
- Define the schema for each API
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),
},
};- Stitch the schemas together
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.