Game of mocks - Mocking a GraphQL API as a proof of concept

2021-01-30
7 min read

Is it worth the trouble?
Is it worth the trouble?

Intro

So you’ve come to a point where it just seems like a good idea to simplify the frontend implementations and get rid of the dozens (dozens) of endpoints scattered throughout your application. The time has come to switch to GraphQL (or you just like shiny, new, things).

GraphQL

For a long time, a classic REST(ful) API has been the de facto standard for data sharing between applications and services. The issue with REST stands in its lack of flexibility, most new use cases on the UI require more work from the backend. Syncing these requirements is a tedious task that requires time and coordination that might be better spent elsewhere.

A new solution appeared in the form of GraphQL which tackles these issues by allowing the client to specify the schema of what it needs. This allows the clients to have more flexibility and gives product managers more power to improve user facing features without worrying about wasting too much time.

The results from a survey made by The State of JavaScript stated that from 20,000 JavaScript developers, 83% are using or intending to learn GraphQL.

How does GraphQL work?

Most of the readers are probably familiar with GraphQL.

GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data.

What it does is it exposes a API endpoints, which allow you to be fully independent of the backend implementation and only worry about the query which is executing on them. This means that you no longer have to rework the backend for every change on the client, if you need another data point that is held in the database, using GraphQL you can fetch it by just adding it to the query.

For example, executing the following query

{
  product {
    name
    current_price
    available_qty
  }
}

Would yield the following results

{
  "product": {
    "name": "Banana",
    "current_price": "I MEAN IT'S ONE BANANA, MICHAEL, WHAT COULD IT COST? TEN DOLLARS?",
    "available_qty": 100001
  }
}

By adding or removing the fields in the query you would get a result with different structure. It is a great way of having flexibility in how you want to build things, and reduce unnecessary payload size if your API is riddled with god endpoints which return half of your database.

Downsides

The biggest downside is additional complexity, as you now have another layer to implement, and in case of issues debug. There is also the need to actually know how to query the API, and the fact that you might expose some database design details depending on how you expose the GraphQL server. And don’t get me started on trying to cache results.

Selling the idea to your VP

So once you reach the point of understanding what GraphQL helps you with, and the downsides aren’t scaring you off, you actually need to persuade your VP that it makes sense to implement it. It sure does sound nice, but what will it look like on the client, how will we actually make it work?

Using mocking to demonstrate value

You can write your own mock server and try to get up and running, but it will be time consuming, and even after spending all that time the idea might not be accepted. We think you should use Mockadillo. With Mockadillo you can do this, depending on the scope of the API, in a very short time period. Let’s demonstrate that.

Real life example

Let’s build a GraphQL backend for a produce store. For this demonstration it’s going to be a pretty simple one.

First we have to define some structure for data. Let’s say we can query for products

type Query {
  product: Product
}

Which has the following structure.

type Product {
  id: String,
  name: String,
  current_price: Int,
  available_qty: Int,
  price_history: [PriceHistory],
  active: Boolean,
}
 
type PriceHistory {
  price: Int
  active_from: Date
  active_to: Date
}

It is obvious here that, if we’re building a storefront, some pages might not need price_history. Other pages might not need the active parameter, where others might (for an admin interface). We can mock these queries easily by using conditions, specifically body request conditions.

Implementing the proof of concept through Mockadillo

After creating the API and Route in your admin dashboard (if you’re unfamiliar with the process visit the getting started page), we need to create and setup the successful Response.

For this demo we see a couple of pages that the client will need:

  • Main page that will return a list of products.
  • A single page that will return detailed product information.
  • A single page that will be shown to admins with extra information.

With these requirements, it’s obvious we need to create 4 different responses. The first one will be a default response, returning an error since it means that the query must have been invalid since we didn’t match any request conditions. The other three represent the data needed for the rest of the pages we will need. We will go into detail for one of these, as the principle is the same for the rest.

List of products response

For this endpoint, we want to return a couple of products, and we assume the page will render certain information limited to

{
    "id": "1",
    "name": "Banana",
    "current_price": 1000,
    "available_qty": 100001,
    "active": true
}

As in most cases we don’t need other fields. Let’s define the conditions:

So at the least we expect the query to contain the keyword products. This means that we will create a new body condition, with the jsonpath value of $.query, using the contains filter, looking for the products value.

Condition requiring ‘products’ string in the query
Condition requiring 'products' string in the query

We can repeat the same process for the fields we want to return, so let’s add 5 more conditions for id, name, current_price, available_qty and active so that the end results looks like this.

Five body conditions for this response
Five body conditions for this response

You could also click on Toggle editing mode to switch to the raw conditions json and paste the following

{
  "headers": [],
  "body": [
    {
      "source": "$.query",
      "kind": "contains",
      "value": "products"
    },
    {
      "source": "$.query",
      "kind": "contains",
      "value": "id"
    },
    {
      "source": "$.query",
      "kind": "contains",
      "value": "name"
    },
    {
      "source": "$.query",
      "kind": "contains",
      "value": "current_price"
    },
    {
      "source": "$.query",
      "kind": "contains",
      "value": "available_qty"
    },
    {
      "source": "$.query",
      "kind": "contains",
      "value": "active"
    }
  ],
  "queryString": [],
  "origin": []
}

And let’s add the response body to show some data to the client

{
  "data": { 
    "products": [
    {
      "id": "1",
      "name": "Banana",
      "current_price": 1000,
      "available_qty": 100001,
      "active": true
    },
    {
      "id": "2",
      "name": "Juice",
      "current_price": 300,
      "available_qty": 55,
      "active": true
    },
    {
      "id": "3",
      "name": "Bread",
      "current_price": 100,
      "available_qty": 8,
      "active": false
    }]
  }
}

Let’s repeat the process for other pages that the application will have. For the details page, according to the GraphQL spec, we expect the query to be similar but to contain a singular product instead of products, and we don’t need the id field for it. On the other hand it might be useful to show the user previous prices (though probably only if they were higher). And for the admin we want to be able to toggle the active field, if we want to disable showing a certain product.

The end result

In the end, we should have the rest of the conditions setup for each of the responses, totaling 4 different responses.

Four different responses, three with conditions
Four different responses, three with conditions

This is pretty much already enough for our POC application, we can start testing.

Testing

For API testing we use Insomnia. Let’s first try to get a list of our products.

The products endpoint returning a list
The products endpoint returning a list

Now let’s see if we can get a single product

The product endpoint returning a single product
The product endpoint returning a single product

Conclusion

In the end, it took us (me) under 5 minutes to create everything that was needed to achieve this. You can go for more granularity and implement more responses to support more use cases. But for now I think this should be enough to show you how Mockadillo can be useful for quickly prototyping a GraphQL application. You can go one step further, plan out the features in more detail, and implement the end schema in Mockadillo. This allows you to, when you are done with the actual implementation, to just swap out the API host URL, and technically your application should work.

Thanks for reading, if you think that you have a similar use case, signup now and try us out

The endpoint is live now here

Nenad Lukic Founder of Mockadillo and a firm believer in reducing any sources of friction and frustrations in the workplace.