MonKey, a simple yet powerful API mocking tool
Tags: opensource, api, node
Published: 2020-01-03 15:38:30

We've all been there. We have all created a few mock objects that look something like this:

```json
{
    "user":"John Doe"
}
```

While working on a project for a company recently, I again saw the importance of proper mocking when our front-end completely broke down when tested against a production database. 

This is often caused when front-end and back-end teams don't work at the same pace. They are almost always a little out of sync. This way valuable time is lost when front-end developers are waiting for API's and data to become available for them.

MonKey is an API mocking tool focused on front-end developers to aid them developing more robust front-ends and to save them time.


## Reasons why I wanted to create MonKey
There are a lot of mocking tools out there of course. Here's why I think MonKey can be different.

### Most API mocking tools are static
Most mocking tools make you define your response yourself. Defining mock objects however, can be very tricky. Your static data probably doesn't include a lot of variety and is not very extensive as it takes a long time to write. 

And besides: if you know what to expect, you will also make sure that it works.

Tests you write yourself will never fail. Think about that one for a second... If you remembered to test it, you probably also remembered to implement it...

MonKey generates data based on a set of rules you define, but the output wil be unique and varied.

### Predefined mock data is often not very realistic
When i'm traveling with my girlfriend, booking hotel and airplane tickets is always a challenge. She is South American and has many surnames with loads of special characters. You would be surprised how many sites she has unintentionally broken over the years.

We often forget to include special cases in our self-defined mocking data. It is crucial that a mocking tool is able to generate realistic data with a high variety. 

MonKey aims to generate data with a high verity and with a large range. Stretching the bounds of the rules that generate your data can help you find issues.

### Mocked datasets are often small and don't resemble production environments
Programmers are notoriously lazy, and therefore we will never create more than a few mock objects. The first time you try your new design against an existing production database you realize you cannot simply do `SELECT * FROM posts` because those 10.000 posts that come back will definitely break your front-end. 

MonKey makes it easy to generate large amounts of data to stress-test your designs on more real-world like scenarios.

### Most mocking tools don't actually simulate AJAX behavior. 
Some popular front-end mocking tools actually generate mocking data in the front-end. This, for me, has two critical flaws. First of all, data is available instantly. It doesn't force you to think about things like loaders, spinners and other visual feedback that your data is being loaded. But even more importantly, you don't create logic for requesting and processing data.

The goal of MonKey was to make it feel and behave like a real-world API. 

### Mocking setups can not be shared
A lot of mocking API services are account or session based, and are very hard to share. Every developer has to setup it's own tests or has to do it over and over again.

MonKey is designed to be very open and easily shareable with other people.

## What I have done so far
Monkey already supports a variety of data types. Most basic types are already available and more can be added easily. 

Recursive models and arrays can be created to generate complex data structures.

MonKey keys can be stored in the browser to easily pick up where you left things. 

## Alright, but let's see some action!
To see MonKey in action click the link below!

> http://monkey.jorislamers.nl/

From the home page, it is possible to generate a new key for your product. If you already have a key, you can enter it here to edit your data models.

> Please don't modify the models I used for this demonstration... Password protection is one improvement that i'm toying with ;)

Let's look at a simple model that MonKey generated: a `User`.

> http://monkey.jorislamers.nl/api/5e0f56dabdf5d708c27598f1/user 

```json
[
   {
      "id":0,
      "name":"Julie Zachery Maitund",
      "email":"Kiley.Oza@gmail.com",
      "password":"Quis"
   }
]
```

> The password function is one on the ToDo list

Now let's see a more complex data model. This time a `Post`. Every post has a banner image, a title and some content text but I also added some metadata to this post: the user who posted it. We can actually include the `User` model in our post model to generate a unique user who posted it.

> http://monkey.jorislamers.nl/api/5e0f56dabdf5d708c27598f1/post

```json
[
   {
      "id":0,
      "banner":"https://picsum.photos/800/600?random&seed=0",
      "title":"Ad consectetur magna minim quis consequat est nulla mollit ipsum",
      "content":"Occaecat velit tempor in occaecat irure tempor consectetur consectetur elit veniam eiusmod veniam irure enim duis occaecat cillum ea in est sint voluptate aliquip voluptate ut fugiat aliqua cillum tempor irure ullamco non laborum proident irure esse anim aute tempor occaecat cillum voluptate est reprehenderit aliquip dolore ipsum eu do eiusmod consequat ea nostrud sit commodo voluptate labore consequat laborum amet anim qui nisi eiusmod nisi adipisicing dolore eiusmod anim occaecat dolor cupidatat voluptate veniam id ipsum irure consequat culpa nostrud id pariatur velit dolore adipisicing nulla sint exercitation elit sunt magna ut non magna ut non nisi nostrud ex ea eiusmod ipsum labore ea est aliquip Lorem aliquip pariatur eiusmod",
      "user":{
         "id":0,
         "name":"Shanna Torras",
         "email":"Nadeen.Orlina@gmail.com",
         "password":"Occaecat"
      }
   }
]
```

Now let's make a `Comment` model, like so:

> http://monkey.jorislamers.nl/api/5e0f56dabdf5d708c27598f1/comment

```json
[
   {
      "id":0,
      "content":"Ea ipsum nisi quis incididunt",
      "user":{
         "id":0,
         "name":"Bunni Newsom Morgun",
         "email":"Sarine.Duky@gmail.com",
         "password":"Fugiat"
      }
   }
]
```

Again we include the `User` model to indicate who posted it.

If we now go back to our `Post` model, we can actually add a list of comments to it.

```json
[
   {
      "id":0,
      "banner":"https://picsum.photos/800/600?random&seed=0",
      "title":"Irure amet ullamco duis nisi aliqua",
      "content":"Cillum occaecat occaecat labore magna voluptate et anim adipisicing sunt ea est elit sint id nisi aute sit do amet laboris et culpa excepteur qui sint culpa non excepteur occaecat consequat id tempor aliqua nulla ipsum sit voluptate aute occaecat velit est fugiat aliqua laborum amet deserunt do velit dolor nostrud occaecat",
      "user":{
         "id":0,
         "name":"Katha Alleyn Center Shiri",
         "email":"Toinette.Boothman@gmail.com",
         "password":"Non"
      },
      "comments":[
         {
            "id":0,
            "content":"Irure mollit ipsum aute pariatur do minim elit anim ut sint enim nostrud eu laboris",
            "user":{
               "id":0,
               "name":"Ethelda Franny Raffaello",
               "email":"Melonie.Mirth@gmail.com",
               "password":"Tempor"
            }
         },
         {
            "id":0,
            "content":"Adipisicing ut et id mollit",
            "user":{
               "id":0,
               "name":"Yetta Brewster Corrine",
               "email":"Mathilde.Autumn@gmail.com",
               "password":"Mollit"
            }
         },
         {
            "id":0,
            "content":"Veniam consequat reprehenderit ex ea ex eiusmod voluptate cupidatat magna sint incididunt eu ipsum deserunt ex velit dolor",
            "user":{
               "id":0,
               "name":"Kristien Eugenius Sherwood",
               "email":"Babb.Dow@gmail.com",
               "password":"Ipsum"
            }
         },
         {
            "id":0,
            "content":"Adipisicing duis proident",
            "user":{
               "id":0,
               "name":"Fredia Thissa",
               "email":"Fredi.Pansy@gmail.com",
               "password":"Do"
            }
         },
         {
            "id":0,
            "content":"Commodo ut ullamco sint voluptate est est officia fugiat ipsum eu",
            "user":{
               "id":0,
               "name":"Alida Napoleon Ardeth Durman",
               "email":"Aurelea.Augusta@gmail.com",
               "password":"Eu"
            }
         }
      ]
   }
]
```

MonKey has now generated a datamodel that includes an array of other models! Neat!

## So what now?
There is room for improvement of course. The idea started after looking for a mocking tool that I liked but not really finding anything. I wrote MonKey over a weekend just to see how far I could get. 

Every-time I use it however, I am surprised about how fast I can generate complex data-models that I need to test my front-end. That's why it feels like a shame to just abandon it and that's why I wrote this piece.

MonKey is not production ready and needs some work to become a robust tool, but i feel like it has potential. 

If you guys think MonKey as a right to exist, I am willing to open source it, to see how far it can go!

Let me know what you think!