Sometimes you may find yourself stuck on your front-end development due to an incomplete or in-progress REST API, but why wait for API developers to finish it in order for you to make a big progress on your front-end development ?
You may even have a great idea for a new project, but instead of spending time on both front-end and back-end developments, you may want to concentrate on the visible part of the project and deliver a great proof-of-concept to quickly gather funds.
Mocking a REST API is the perfect quick-win strategy for a lot of use cases.
So let’s get started !
Demo app
For the purposes of this article, let’s say you want to create a lightweight task manager. A simple REST API must allow you to:
- create a task,
- get the details of a specific task,
- update a task,
- remove a task.
What is needed is an API with an endpoint /tasks
:
GET /tasks
will retrieve all tasks,POST /tasks
will create a new task,GET /tasks/:id
will retrieve a single task for a given id,PATCH /tasks/:id
will update a property of a given task,DELETE /tasks/:id
will remove a specific task.
Installation
Start an empty project and install bouchon@0.4.0
$ mkdir bouchon-tasks && cd $_
(bouchon-tasks)$ npm init
(bouchon-tasks)$ npm install bouchon --save-dev
Examples will be written in ES2015, therefore you have to install
(bouchon-tasks)$ npm install babel-core babel-polyfill babel-preset-es2015 babel-plugin-transform-object-rest-spread --save-dev
and create a .babelrc
file.
// bouchon-tasks/.babelrc{
"presets": [ "es2015" ],
"plugins": ["transform-object-rest-spread"]
}
Basic GET endpoint
Create a folder representing your endpoint
(bouchon-tasks)$ mkdir tasks
Then add a first fixture in a JSON file that will be saved later in the state
Then, let’s create your basic set of actions/selectors/reducer to GET
all tasks, and the set of routes representing the endpoints
At this point, if you start bouchon it won’t work because it is looking for files ending with .fixture.js
. The lib’s doc suggests an easy tweak which consist in creating an all.fixture.js
file at the root of the project, requiring all of your fixtures.
Let’s see how to start bouchon for real this time
(bouchon-tasks)$ ./node_modules/.bin/bouchon --helpUsage: bouchon [options]Options: -h, --help output usage information
-d, --path [path/to/fixtures] Path to the fixtures
-p, --port <port> Port of the server
--hot Enable hot-reload
The path to fixtures seems to be the only mandatory option, while the default port number will be 3000
and hot reloading is disabled by default.
(bouchon-tasks)$ ./node_modules/.bin/bouchon -d .
13:37:42.365Z INFO server: Initializing store...
13:37:42.372Z INFO server: Registering "GET /tasks/"
13:37:42.910Z INFO server: ✔ Store is ready.
13:37:42.911Z INFO server: ✔ App listening at port 3000.
TheGET /carts
endpoint is registered and available, so let’s test it
$ curl http://localhost:3000/tasks | jq .
[
{
"description": "Use bouchon to mock all my apis",
"id": 1,
"status": "open",
"title": "My first task"
}
]
Congrats on your first endpoint !
Advanced endpoint
Let’s add the POST /tasks
endpoint which should be a bit more complicated
What is important here is that we created for our reducer a handler function createTaskHandler
handling thecreate
action, and then added a selector to getCreatedTask
.
Let’s try to see if the new route will be registered
(bouchon-tasks)$ ./node_modules/.bin/bouchon -d .
15:01:48.179Z INFO server: Initializing store...
15:01:48.183Z INFO server: Registering "GET /tasks/"
15:01:48.184Z INFO server: Registering "POST /tasks/"
15:01:48.699Z INFO server: ✔ Store is ready.
15:01:48.700Z INFO server: ✔ App listening at port 3000.
Send a POST
command to create a new task
$ curl -H "Content-Type: application/json" -X POST -d '{"description":"My task created with curl","title":"Curl"}' http://localhost:3000/tasks | jq .
{
"id": 2,
"message": "Task Created"
}
The new task seems to be created. Let’s check out the newly returned structure for our GET /tasks
$ curl http://localhost:3000/tasks | jq .
[
{
"description": "Use bouchon to mock all my apis",
"id": 1,
"status": "open",
"title": "My first task"
},
{
"description": "My task created with curl",
"id": 2,
"status": "open",
"title": "Curl"
}
]
Well that was quite easy, right ?
Conclusion
This was a very quick overview and you can check out the complete demo app on Github for the getOne
, update
and delete
actions.
I find it being a very complete tool for the purposes of prototyping. It has been more than a year that we use this at Gandi.net, and it helps in our every day front-end developments in order to deliver features before even having the complete APIs, signatures are more than enough to begin with.
Here’s a few things from the list of what’s left to discover with bouchon:
- Namespacing your fixtures to simulate multiple APIs,
- Delaying an action in order to simulate a slow API,
- Actions that will be dispatched in a future to simulate an asynchronous backend,
- Force error status codes to simulate diversified API crashes,
- Middle-wares that can help achieving absolutely everything (i.e., pagination headers, parameters validation, default response etc.),
- Hot reloading JSON fixtures.
Github links
- bouchon: efficient API mocking.
- bouchon-tasks: the demo app for this article.
- bouchon-toolbox: a set of useful reducers, selectors and middle-wares for common use cases.
- bouchon-samples: some examples for inspiration.
@cr0cK , the creator of bouchon has very well documented the whole project, so it’s worth opening issues and pull requests knowing that a major update is coming for a 1.0.0.