Migrating from Schemaless REST API to GraphQL without writing any code
GraphQL was originally created in order to easily provide a powerful API on top of existing code. The current approach people are using today while migrating from REST API to GraphQL is to create a new schema and use GraphQL as a proxy. That has a lot of benefits because it gives us an opportunity to rethink the API and improve it, without changing the underlining services.
Let’s first start with looking at that approach:
Implementing a Basic Proxy GraphQL Backend
Let’s say you have /user
endpoint that does all CRUD operations for User
entity with different
HTTP methods, and you would need a GraphQL schema like below;
type Query {
user(id: ID): User
}
type Mutation {
createUser(input: UserInput): User
updateUser(id: ID, input: UserInput): User
deleteUser(id: ID): ID
}
type User {
id: ID
name: String
age: Int
}
input UserInput {
name: String
age: Int
}
And you would also need a thin business logic that proxies upcoming GraphQL requests to the REST API using GraphQL resolvers like below;
module.exports = {
Query: {
user: (root, args) => fetch('https://myrest.com/user/' + args.id).then(res => res.json())
},
Mutation: {
createUser: (root, args) =>
fetch('https://myrest.com/user', {
method: 'PUT',
body: JSON.stringify(args.input)
}).then(res => res.json()),
updateUser: (root, args) =>
fetch('https://myrest.com/user' + args.id, {
method: 'POST',
body: JSON.stringify(args.input)
}).then(res => res.json()),
deleteUser: (root, args) =>
fetch('https://myrest.com/user' + args.id, {
method: 'DELETE'
}).then(res => res.json())
}
}
This example assumes that you have /user/:id
endpoint that gets a User
entity with HTTP GET
,
deletes user with HTTP DELETE
and updates a User
that has the given id with the given input.
Also /user
endpoint creates a new User
with the given input.
But this implementation will be hard to maintain when the REST API is updated and become bigger.
Using GraphQL Mesh Instead without Any Code
GraphQL Mesh is a tool that handles multiple non-GraphQL data sources and generates an executable GraphQL schema on top of them with a simple configuration file. You can check the announcement blog post to learn more
On top of having handlers that automatically take care of sources with schema like - OpenAPI/Swagger, gRPC, SOAP, and others, it also has JSON Schema handler that generates a GraphQL Schema based on the given JSON schema files. This handler can also generate JSON Schema on runtime based on the given sample request and response data.
First you need to create a project using yarn
on an empty directory:
yarn init
After that we need to install some dependencies of Mesh:
yarn add @graphql-mesh/cli @graphql-mesh/json-schema graphql
Create a .meshrc.yml
which is a configuration file for GraphQL Mesh on our new project:
sources:
- name: MyRest
handler:
jsonSchema:
baseUrl: https://myrest.com/
operations:
- type: Query
field: user
path: /user/{args.id}
method: GET
responseSample: ./getUserResponse.json
- type: Mutation
field: createUser
path: /user
method: PUT
requestSample: ./createUserRequest.json
responseSample: ./createUserResponse.json
- type: Mutation
field: updateUser
path: /user/{args.id}
method: POST
requestSample: ./updateUserRequest.json
responseSample: ./updateUserResponse.json
- type: Mutation
field: deleteUser
path: /user/{args.id}
method: DELETE
responseSample: ./deleteUserResponse.json
As you can see in the configuration, we defined our endpoints without a single line of code. After creating this configuration file. We need to get sample request and response files by calling those endpoints on our local.
With a single command, our new GraphQL endpoint is ready to serve;
yarn mesh serve
Not Only as a Gateway but Also a Completely Type-Safe SDK
Mesh is able to generate a type-safe SDK from generated GraphQL API because the generated GraphQL
schema is a local GraphQLSchema
that can be executed without binding an HTTP server.
That means you can use GraphQL Mesh inside your existing services or clients, as an SDK, just as a simple dependency, without adding another box in your architecture.
Join our newsletter
Want to hear from us when there's something new?
Sign up and stay up to date!
*By subscribing, you agree with Beehiiv’s Terms of Service and Privacy Policy.