GRAPHQL Mesh
Unify multiple API sources into a single GraphQL endpoint with GraphQL Mesh.
You are a GraphQL Mesh specialist who builds unified API layers from heterogeneous data sources. GraphQL Mesh automatically generates a GraphQL schema from REST APIs, OpenAPI specs, gRPC services, databases, and other GraphQL endpoints, then merges them into a single queryable gateway. You configure sources, transforms, and caching to create a cohesive API without rewriting backend services. ## Key Points - **Exposing all upstream fields without filtering** -- auto-generated schemas include every endpoint; use `filterSchema` to remove internal, debug, or deprecated operations from your public gateway. - **Skipping response caching** -- Mesh adds network overhead by proxying requests; always configure caching for read-heavy queries to offset the additional latency. - **Using Mesh as the only data validation layer** -- Mesh validates GraphQL input types but does not replace backend validation; upstream services must still validate their own inputs. - **Ignoring N+1 query problems in cross-source resolvers** -- additional resolvers that fetch related data per-item create N+1 patterns; use batch endpoints or DataLoader patterns when available. - You have multiple backend services (REST, gRPC, GraphQL, databases) and want a single GraphQL endpoint without rewriting backends. - You are migrating from REST to GraphQL incrementally and need to wrap existing OpenAPI services as GraphQL sources. - You need cross-service data stitching where a query joins data from multiple independent APIs in a single request. - You want a gateway that auto-generates its schema from upstream API definitions, keeping the gateway config minimal. - You need to filter, rename, and reshape auto-generated schemas to present a clean public API surface. ## Quick Example ```bash npm install @graphql-mesh/cli @graphql-mesh/compose-cli npm install @graphql-mesh/openapi-source @graphql-mesh/graphql-source npm install @graphql-mesh/transform-rename @graphql-mesh/transform-filter-schema ``` ```bash MESH_PORT=4000 MESH_HOSTNAME=0.0.0.0 USERS_API_URL=https://api.example.com PAYMENTS_API_URL=https://payments.example.com/graphql ```
skilldb get api-gateway-services-skills/GRAPHQL MeshFull skill: 227 linesGraphQL Mesh
You are a GraphQL Mesh specialist who builds unified API layers from heterogeneous data sources. GraphQL Mesh automatically generates a GraphQL schema from REST APIs, OpenAPI specs, gRPC services, databases, and other GraphQL endpoints, then merges them into a single queryable gateway. You configure sources, transforms, and caching to create a cohesive API without rewriting backend services.
Core Philosophy
Schema-First From Existing APIs
GraphQL Mesh generates GraphQL schemas from existing API definitions rather than requiring you to write resolvers manually. Point Mesh at an OpenAPI spec, a gRPC proto file, or a database connection string, and it produces a fully-typed GraphQL schema automatically. This means adopting GraphQL without modifying any backend service. The source of truth remains the upstream API definition.
Transforms for Schema Refinement
Auto-generated schemas often have awkward naming, deeply nested types, or fields you want to hide. Mesh transforms reshape the schema after generation: rename types and fields, filter out internal endpoints, add computed fields, or merge types across sources by shared keys. Transforms are declarative and composable, applied in order during schema construction.
Source Composition Over Federation
Unlike Apollo Federation which requires each service to implement the Federation spec, Mesh composes any source regardless of its protocol or awareness of GraphQL. A REST API, a PostgreSQL database, and a gRPC service can be queried together in a single GraphQL operation. Mesh handles the orchestration, batching, and data merging transparently.
Setup
Install / Configuration
npm install @graphql-mesh/cli @graphql-mesh/compose-cli
npm install @graphql-mesh/openapi-source @graphql-mesh/graphql-source
npm install @graphql-mesh/transform-rename @graphql-mesh/transform-filter-schema
// mesh.config.ts
import { defineConfig } from "@graphql-mesh/compose-cli";
import { loadOpenAPISubgraph } from "@graphql-mesh/openapi-source";
import { loadGraphQLSubgraph } from "@graphql-mesh/graphql-source";
export const composeConfig = defineConfig({
subgraphs: [
{
sourceHandler: loadOpenAPISubgraph("UsersAPI", {
source: "https://api.example.com/openapi.json",
endpoint: "https://api.example.com",
}),
},
{
sourceHandler: loadGraphQLSubgraph("PaymentsAPI", {
endpoint: "https://payments.example.com/graphql",
}),
},
],
});
Environment Variables
MESH_PORT=4000
MESH_HOSTNAME=0.0.0.0
USERS_API_URL=https://api.example.com
PAYMENTS_API_URL=https://payments.example.com/graphql
Key Patterns
1. OpenAPI Source with Endpoint Configuration
// mesh.config.ts
import { defineConfig } from "@graphql-mesh/compose-cli";
import { loadOpenAPISubgraph } from "@graphql-mesh/openapi-source";
export const composeConfig = defineConfig({
subgraphs: [
{
sourceHandler: loadOpenAPISubgraph("PetStore", {
source: "./petstore-openapi.yaml",
endpoint: "{env.PETSTORE_API_URL}",
operationHeaders: {
Authorization: "Bearer {env.PETSTORE_API_TOKEN}",
},
}),
},
],
});
2. Type Merging Across Sources
// Merge User type from two different sources by shared 'id' field
import { defineConfig } from "@graphql-mesh/compose-cli";
import { loadOpenAPISubgraph } from "@graphql-mesh/openapi-source";
export const composeConfig = defineConfig({
subgraphs: [
{
sourceHandler: loadOpenAPISubgraph("UsersAPI", {
source: "./users-openapi.yaml",
endpoint: "{env.USERS_API_URL}",
}),
transforms: [
{
rename: {
renames: [
{ from: { type: "User_Response" }, to: { type: "User" } },
],
},
},
],
},
{
sourceHandler: loadOpenAPISubgraph("OrdersAPI", {
source: "./orders-openapi.yaml",
endpoint: "{env.ORDERS_API_URL}",
}),
},
],
});
3. Additional Resolvers for Cross-Source Links
// mesh.config.ts
export const composeConfig = defineConfig({
subgraphs: [/* ... sources ... */],
additionalTypeDefs: /* GraphQL */ `
extend type Order {
customer: User
}
`,
additionalResolvers: [
{
type: "Order",
field: "customer",
targetSource: "UsersAPI",
targetMethod: "getUserById",
requiredSelectionSet: "{ customerId }",
returnType: "User",
args: {
id: "{root.customerId}",
},
},
],
});
Common Patterns
Caching Responses
// Gateway-level response caching
import { createGatewayRuntime } from "@graphql-mesh/serve-runtime";
import { useResponseCache } from "@graphql-yoga/plugin-response-cache";
const gateway = createGatewayRuntime({
supergraph: "./supergraph.graphql",
plugins: () => [
useResponseCache({
session: (request) => request.headers.get("authorization"),
ttl: 60_000, // 60 seconds
ttlPerType: {
Product: 300_000, // 5 minutes for products
},
}),
],
});
gRPC Source Integration
import { loadGrpcSubgraph } from "@graphql-mesh/grpc-source";
export const composeConfig = defineConfig({
subgraphs: [
{
sourceHandler: loadGrpcSubgraph("InventoryService", {
endpoint: "{env.INVENTORY_GRPC_URL}",
source: "./protos/inventory.proto",
}),
},
],
});
Schema Filtering
// Remove internal endpoints from the public schema
{
sourceHandler: loadOpenAPISubgraph("InternalAPI", {
source: "./internal-openapi.yaml",
endpoint: "{env.INTERNAL_API_URL}",
}),
transforms: [
{
filterSchema: {
filters: [
"Query.!internal*", // Exclude queries starting with "internal"
"Mutation.!debug*", // Exclude debug mutations
],
},
},
],
}
Anti-Patterns
- Exposing all upstream fields without filtering -- auto-generated schemas include every endpoint; use
filterSchemato remove internal, debug, or deprecated operations from your public gateway. - Skipping response caching -- Mesh adds network overhead by proxying requests; always configure caching for read-heavy queries to offset the additional latency.
- Using Mesh as the only data validation layer -- Mesh validates GraphQL input types but does not replace backend validation; upstream services must still validate their own inputs.
- Ignoring N+1 query problems in cross-source resolvers -- additional resolvers that fetch related data per-item create N+1 patterns; use batch endpoints or DataLoader patterns when available.
When to Use
- You have multiple backend services (REST, gRPC, GraphQL, databases) and want a single GraphQL endpoint without rewriting backends.
- You are migrating from REST to GraphQL incrementally and need to wrap existing OpenAPI services as GraphQL sources.
- You need cross-service data stitching where a query joins data from multiple independent APIs in a single request.
- You want a gateway that auto-generates its schema from upstream API definitions, keeping the gateway config minimal.
- You need to filter, rename, and reshape auto-generated schemas to present a clean public API surface.
Install this skill directly: skilldb add api-gateway-services-skills
Related Skills
Apisix
Apache APISIX is a dynamic, real-time, high-performance API Gateway built on Nginx and LuaJIT, designed for managing
AWS API Gateway
Build and manage APIs with AWS API Gateway including REST, HTTP, and WebSocket APIs.
Cloudflare Workers
Build and deploy edge computing applications with Cloudflare Workers.
Express Gateway
Express Gateway is an API Gateway built on Express.js, offering powerful features for proxying,
Fastify
Fastify is a highly performant, low-overhead web framework for Node.js, designed to be as fast as possible in terms of both throughput and response time.
Gravitee
Gravitee is an open-source, flexible, and high-performance API Management platform that helps you