Create a Remote Schema to wrap a REST API with Hasura
What is a Remote Schema
A remote schema is simply an external GraphQL service that you can stitch with Hasura GraphQL Engine for a unified GraphQL API. A common way to incrementally adopt GraphQL in an existing infrastructure, is to wrap pre-existing REST APIs within a GraphQL layer. In this blogpost, we will see how you can do this using Hasura easily.
Example REST API
Suppose, you have a REST API like the following:
GET /users
GET /users/:userId
POST /users
The GET /users endpoint also takes an optional query param i.e. GET /users?name=abc and the POST /users endpoint expects a valid JSON payload in the body.
This boilerplate is built using the Apollo Server framework. It is simply a hello schema i.e. on query { hello } it returns { data": {"hello": "world"} }
For our REST API (from above), lets start defining some new types and fields. The complete definition of types and fields is what makes our schema :
const typeDefs = gql`
type User {
id: String!
name: String!
balance: Int!
}
type Query {
getUser(id: String!): User
users(name: String): [User]
}
type Mutation {
addUser(name: String!, balance: Int!): User
}
`;
Roughly our REST to GraphQL mapping looks like the following:
REST
GraphQL
GET /users
users (name: String) : [User]
GET /users/:userId
getUser(id: String!): User
POST /users
addUser(name: String!, balance: Int!): User
We can already notice some extra information about the APIs and this is one of the selling points of GraphQL: we can see input and output type information very clearly. Lets now move to implementing the APIs.
Resolve!
In a REST world, we usually talk about writing handlers for endpoints. In GraphQL, we do a similar thing but call it resolvers!
For the schema that we defined in the previous section, lets add their corresponding resolvers:
Easy! All we did was proxy the incoming GraphQL request to our REST API.
Finally, we need to deploy this service somewhere and get a URL. There are plenty of cloud solutions that allow you to deploy a Node service easily. You can look at the final implementation with deployment instructions on Heroku here.
Add to Hasura
Once you have gotten an HTTP URL for your above GraphQL service, just head over to your Hasura console and add it as a Remote Schema. In case your remote schema defines few types that are same as Hasura, they will get merged automatically too. Notice that you can also add Authorization and other headers to your Remote Schema in case your REST API expects such headers.
Now, you should be able to call your remote schema APIs alongwith the default Hasura APIs from the Hasura GraphQL Endpoint. And that's it!
Conclusion
It is easy to wrap your existing REST API into a GraphQL API. The advantages of these are many:
1) you can incrementally adopt GraphQL in your existing infrastructure,
2) you get added benefits over REST APIs like type safety and more readability,
3) you get a unified API layer for all your APIs.
With the guide presented above, you can get started with your GraphQL wrapped REST API in minutes. You can then add this GraphQL service as a Remote Schema in Hasura for automatic schema-stitching.