Amir Hoseinian

About

Breaking the comfort zone

As developers, we constantly ask ourselves: Is our current approach the best for the problems we are tackling? One could ask this question about transferring data between backends and frontends. REST APIs have been the tool of choice for generations. But they have been losing their dominance in the past years. Tools like Graphql are rapidly gaining popularity and becoming more widespread. Therefor, in this article, we are exploring how we can proxy a simple REST endpoint into a Graphql.

GraphQL provides some benefits over REST APIs.

  • Clients have the ability to dictate exactly what they need from the server
  • Data is typed and it has null checks
  • Type generation libraries for most languages
  • Documentation on the API

Entring the unfamiliar situation

To experiment with a simple GraphQL API we will turn the cats' facts public API into a GraphQL node.

Start an express server

Probably you have seen the code below before if you ever heard of express and nodejs backends. it is a minimal HTTP server implementation listening on port 3000, if you need to learn more about ExpressJS here is where you can find out more docs

const express = require("express");
const app = express();

const PORT_NUMBER = 3000;

app.get("/", (req, res, next) => res.json({ success: true }));

app.listen(PORT_NUMBER, () => {
  console.log(`Server running on port ${PORT_NUMBER}`);
});

Define the types

There are three types of main Nodes in Graphql: Query, Mutation and Subscription. A Query is where we define nodes that are handling retrieving data similar to the get request in REST.

In our simple schema, we create the type Cat with the name, fact (an interesting fact about the cat) and votes. And then define the node cats as an Array of Cats.

var { graphql, buildSchema } = require('graphql');

var schema = buildSchema(`
  type Query {
    cats: [Cat],
  }

  type Cat {
    name: String,
    fact: String,
    votes: Int,
  }
`);

Implement resolvers

Then we have to create the root object which tells the Graphql server how to retrieve the data for each node in our graph. Here we have the key cats with the value of a function that would resolve to an array of objects with the same type as Cat in our schema.

var root = {
  /// resolvers can be either sync or async
  cats: async function() {


    const cats = await axios.get("https://cat-fact.herokuapp.com/facts");

    const result = convertJsonCatsToGqlCats(cats);

    return result;
  }
};

And the last step is to bring it all together with the help of graphqlHTTP middleware.

const graphqlHTTP = require("express-graphql");

app.use(
  "/graphql",
  graphqlHTTP({
    schema: schema,
    rootValue: root,
    graphiql: true
  })
);

The server should be usable now and we can access the Graphql endpoint on localhost:3000/graphql.

Furthermore, you can check the appolo-server out which offers some benefits over the standart implementation above.

The code above lives here.