Prompt
How do I generate a GraphQL API from existing REST APIs?
Latest observation
You generally do this by building a GraphQL layer (gateway/facade) on top of your existing REST endpoints, rather than “converting” REST into GraphQL automatically.
Common approaches
1. Write a GraphQL server that wraps REST
Create GraphQL types, queries, and mutations, then implement resolvers that call your REST APIs.
Example flow:
- GraphQL query:
user(id: "1") - Resolver calls:
GET /users/1 - Resolver maps REST response into GraphQL schema
This is the most flexible and common approach.
2. Use API composition / GraphQL gateway
If you have multiple REST services, place a single GraphQL gateway in front of them.
Benefits:
- One GraphQL endpoint for clients
- Aggregates data from multiple REST APIs
- Hides backend complexity
- Allows client-specific shaping of data
3. Use code generation / scaffolding tools
Some tools help you bootstrap GraphQL from REST/OpenAPI specs, then you customize the parts that need business logic.
Helpful if your REST APIs already have:
- OpenAPI/Swagger definitions
- Consistent resource models
- Stable endpoints
Examples of useful tools/approaches:
- GraphQL Mesh: can wrap REST/OpenAPI and expose GraphQL quickly
- Apollo Server + custom resolvers
- Hasura / PostGraphile are more for databases, not REST
- Hot Chocolate (C#) / Spring for GraphQL (Java) if you want to build a gateway in those ecosystems
Typical architecture
-
Define GraphQL schema
- Types:
User,Order,Product - Queries:
user,orders,product - Mutations:
createOrder,updateUser
- Types:
-
Implement resolvers
- Each resolver calls one or more REST endpoints
- Map REST fields to GraphQL fields
-
Handle performance
- Use batching/caching to avoid N+1 REST calls
- Consider DataLoader or request-level caching
-
Add auth and error handling
- Forward tokens to REST services
- Translate REST errors into GraphQL-friendly errors
-
Expose a single GraphQL endpoint
- Clients use GraphQL
- REST stays behind the scenes
Simple example
GraphQL schema
type User {
id: ID!
name: String!
email: String
}
type Query {
user(id: ID!): User
}
Resolver
const resolvers = {
Query: {
user: async (_, { id }, { restClient }) => {
const res = await restClient.get(`/users/${id}`);
return res.data;
}
}
};
Things to watch out for
- N+1 problem: GraphQL can trigger many REST calls if nested fields are resolved independently
- Over-fetching/under-fetching: GraphQL helps clients, but your resolvers still need efficient backend calls
- Schema design: Don’t mirror REST 1:1 blindly; model the API around client needs
- Pagination: Standardize how REST pagination maps to GraphQL connections or lists
- Versioning: GraphQL usually evolves by adding fields instead of versioning endpoints
If you want the fastest path
If you already have OpenAPI/Swagger specs, try GraphQL Mesh first. It can often generate a GraphQL layer over REST APIs with minimal code.
If you want, I can show you:
- a Node.js/Apollo example,
- a GraphQL Mesh setup, or
- how to do this from an OpenAPI spec.
Brands