Taming network with redux-requests, part 8 - Mocking and multiple drivers
Tags: javascript, redux, react, webdev
Published: 2020-07-30 14:06:31

In the [previous part of this series](https://dev.to/klis87/taming-network-with-redux-requests-part-7-caching-2i3c) we discussed caching.

In this part we will cover mocking and a possibility to use multiple drivers in one app.

## What is mocking and when it is useful?

Mocking is like faking. Sometimes, usually as front-end developer you happen to be in a position when you need to work on a feature but this feature requires to integrate with back-end. Often back-end could be not ready yet or just buggy. Not always you can afford to wait, what to do then? The answer is mocking. You can mock some server responses and start working before API is finished, and then, once it is, you can replace mocked responses with real ones. In real life this happens so often that it would be great to make this process as easy as possible. Fortunately `redux-requests` has a dedicated driver for such a situation!

## Using `mock` driver

As you probably noticed, `redux-requests` supports drivers concept. You can use it with `axios`, `Fetch API`, `GraphQL`, anything! You can write your own drivers. You can even use multiple at the same time. One of those drivers is `mock` driver. Let's see how to use it and how it could help us when we don't have back-end finished and we want to start working.
 
To install the package, just run:
```bash
$ npm install @redux-requests/mock
```

Then, as always, pass it to `handleRequests` first:
```js
import { handleRequests } from '@redux-requests/core';
import { createDriver } from '@redux-requests/mock';

handleRequests({
  driver: createDriver({
    // optional, in ms, defining how much time mock request would take, useful for testing spinners
    timeout: 1000,
  }),
});
```

Then, start using it inside your request actions:
```js
const fetchPhoto = id => ({
  type: FETCH_PHOTO,
  request: {
    response: {
      data: {
        id,
        title: 'accusamus beatae ad facilis cum similique qui sunt',
      },
    },
  },
});

const fetchPhotoWhichWillFail = id => ({
  type: FETCH_PHOTO_WHICH_WILL_FAIL,
  request: {
    error: { status: 404 },
  },
});
```

Also note, that for mutations you need to pass `meta.asMutation: true` in your request actions, so the core library could know whether a request is a query or a mutation. For many drivers like `axios`, `fetch` and `graphql` it is not usually necessary as the library can deduct whether something is a query or a mutation by looking at request config, like `GET` request method will be typically a query while `POST` a mutation.

Anyway, this is all there is to it! Then, once part/all of mocked endpoints are finished, all you need to do is to replace `mock` driver with something else, like `axios`. All other things will become unchanged. This is one of the reasons why driver approach could be handy.

Ok, but there is one last thing. Usually you won't mock everything. So how to use `mock` driver for some actions and another like `axios` in others? For that you need to use multiple drivers.

## Using multiple drivers

Multiple drivers are useful especially for mocking scenario. But it could be also great if for instance you use multiple ways to communicate with server/servers, like `axios` together with `graphql`. In could be also useful when you would like to switch from `axios` to `Fetch API` for instance without refactoring everything at the same time, but gradually. Anyway, let's see how to do it with `axios` and `mock` drivers together: 
```js
import axios from 'axios';
import { handleRequests } from '@redux-requests/core';
import { createDriver as createAxiosDriver } from '@redux-requests/axios';
import { createDriver as createMockDriver } from '@redux-requests/mock';

handleRequests({
  driver: {
    default: createAxiosDriver(axios),
    mock: createMockDriver({ timeout: 1000 }),
  },
});
```

As you can see, the default driver is `axios`, so how to mark a request to be run by mock driver? Just pass the key you assigned to `mock` driver (`mock` in our case) in `action.meta.driver`, for instance:
```js
const fetchPhoto = id => ({
  type: FETCH_PHOTO,
  request: {
    response: {
      data: {
        id,
        title: 'accusamus beatae ad facilis cum similique qui sunt',
      },
    },
  },
  meta: { driver: 'mock' },
});
```

Then, once `fetchPhoto` is ready on the back-end, you could refactor it to something like that:
```js
const fetchPhoto = id => ({
  type: FETCH_PHOTO,
  request: {
    url: `/photo/${id}`,
  },
});
```

With such an approach, you could really surprise your team, you could easily integrate your app with a new and shiny back-end in minutes!

## What's next?

In [the next part](https://dev.to/klis87/taming-network-with-redux-requests-part-9-external-libraries-and-promises-1no9) we will cover using `redux-requests` with promise based libraries.