No API? Fake it until you make it!
Tags: javascript, tutorial, beginners
Published: 2020-04-30 21:27:08

You want some data for your new project and regardless of the technology you are going to use, making an API is not always straightforward or you simply don't want to wait until the back end team is going to expose the endpoints for you.
One of the solutions is to Mock the API and mocking is nothing but imitating the server response.
Here is a sketch of the idea:

![Mock API sketch](https://res.cloudinary.com/irosgrim/image/upload/v1588280350/sketch_va2isn.png)

### Explanation:
Whenever we make a HTTP request, a function will check what environment we are in and based on that it will return real or mock data.

The environment can be determined in various ways but for this example we will switch it with a URL query string of our choice:

`http://localhost:8080/mockapi.html?dev=true`

The relevant part of the URL is the `?dev=true` but it can be anything we want: `?mock=true`, `?mickeymouse`, `?sendnudes`, etc.
Example:

`http://localhost:8080/mockapi.html?mickeymouse&handsome=true`

### Let's build something

For the sake of simplicity, we will avoid frameworks and dependencies but we will consider https://jsonplaceholder.typicode.com/posts/ as our "real" API endpoint.
If you didn't know, https://jsonplaceholder.typicode.com is a "Fake Online REST API for Testing and Prototyping" which is very handy when you need some data in JSON format. The only downside is that you can't really delete or modify anything but you will get a fake response on such attempts.

### The interceptor function

This is the "brain" of our Mock API and this function alone would be enough to mock any request but because for many people ( including myself ) making a practical example is more helpful, we are going to create a very simple project (like very, very, very simple). 
In our project we are going to GET and display a list of articles, we are going to POST new articles and we are going to DELETE articles.

We will call this function whenever we want to make a request and it will act as a switch between the mock data and the real data:

```js
function makeRequest() {
  const env = window.location.href.indexOf('dev=true') > -1 
    ? 'development' 
    : 'production';
  if(env === 'development') {
    environmentSticker.innerHTML = `
      <img src="./imgs/mock.png">
    `;
    return new MockAPI();
  } else {
    environmentSticker.innerHTML = `
      <img src="./imgs/real.png">
    `;
    return new RealAPI();
  }
}
```

` const env = window.location.href.indexOf('dev=true') > -1 `

This line of code determines if `dev=true` string is present in the current document URL. 
`if(env === 'development') `  then all the requests will be redirected to our Mock API otherwise towards the real API.

**RealAPI()** is a constructor function that will allow us to make a custom request. 
In this example I chose to use the `fetch API` just because I wanted to avoid dependencies but you can use whatever you want (Axios is awesome).


```js
function RealAPI() {
  this.$fetch = async (url, config = {}) => {
    const realData = await fetch(url, config);
    const response = await realData.json();
    return response;
  }
}
```

**MockAPI()** is also a constructor function and here is where we mock the requests and responses.

```js
function MockAPI() {
  this.$fetch = async (url, config = {}) => {
    switch(config.method) {
      case undefined:
      case 'GET':
        await delay(1000);
        return await mockData;

      case 'POST':
        if(config.body) {
          const newEntry = JSON.parse(config.body);
          mockData.unshift(newEntry);
          updateArticles(mockData);
          return await {};

        } else {
          console.log('body is missing');
          break;

        }

      case 'DELETE':
        const articleId = parseInt(url.substring(url.lastIndexOf('/') + 1));
        mockData = mockData.filter(article => article.id !== articleId);
        updateArticles(mockData);
        return await {};
    }
  }
}
```
The `$fetch` method is our proxy for the HTTP requests. If no config argument is present then we assume it's a `GET` HTTP request otherwise it is the method specified in `config.method` (check [Fetch API documentation on MDN](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)).
Since we want our UI to handle errors and delays, here we can mock return errors and delayed responses. That's pretty much it.

I tried to outline the main functions but at the end of the article you will find a link to the source code that you can explore in more detail plus a link to a live example.

Here is a screenshot of the app:

![Mock API screenshot](https://res.cloudinary.com/irosgrim/image/upload/v1588280350/mock-screenshot_zjd7ji.png)


**DONE!**

Now you can fake your own API but the best part is that you can have total control over it.

The full code can be seen here:
https://repl.it/@irosgrim/StormyDevotedVirtualmemory

**Mock API:**
https://stormydevotedvirtualmemory--irosgrim.repl.co/?dev=true

**"Real" API:**
https://stormydevotedvirtualmemory--irosgrim.repl.co/


A big thank you to all the people that found the courage to share their knowledge and passion through articles and tutorials. You helped me more than you will ever know!

Did you find any errors in my example? Sorry about that, I'll try better next time.