/restdouble

Run a fake REST service to use as a test double or as a backend for rapid frontend prototyping.

Primary LanguageJavaScriptMIT LicenseMIT

restdouble

Run a fake REST service to use as a test double or as a backend for rapid frontend prototyping.

restdouble allows to serve string, JSON, and binary data through easy configuration.

Quick Start

Install restdouble

npm install -g restdouble

Define your API in YAML format

    # api.yaml
    - path: /
      status: 200
      response: My API
    - path: /static/img.png
      file: ./myfiles/img.png
    - path: /api/users/1
      method: GET
      response: {"id": 1, "name": "user1"}
    - path: /api/users/1
      method: PUT
      response: {"id": 1, "name": "user1", "status": "updated"}
    - path: /api/users
      response: [{"id": 1, "name": "user1"}, {"id": 2, "name": "user2"}] 

Each item defines a route, which can have the following keys:

    path: REST resource defining the route (default: '/')
    method: HTTP method name (default: 'ANY')
    status: HTTP response code (default: 200)
    file: Path to a file to be served
    response: String or JSON object to be served
    hook: Name of the custom request handler method

See the Section on defining hook methods for more information.

Start Server

restdouble start -a api.yaml

By default the server starts on localhost:3000. You can start the server on a different port by using the -p option.

restdouble start -a api.yaml -p 8888

Access API

Now you can access all the routes defined in your API description. For instance, the curl command below:

curl --request GET http://localhost:3000/api/users

returns:

[{  
  "id": 1,
  "name": "user1"
 },
 {  
  "id": 2,
  "name": "user2"
}]

You can access a route using any HTTP method unless you restrict this behaviour by defining a HTTP method in the API description file.

Use URL Variables

You can define a URL variable starting a segment with a colon ':'. You can then substitue the URL variable with any string when making an HTTP request.

- path: /api/users/:userid/friends
  response: [{"id": 3, "name": "user3"}, {"id": 4, "name": "user4"}]

Note that if a request matches with multiple routes, the most specific one will be evaluated.

Define Hook Methods

If you need more detailed control over an API route, you can define a hook method that will be invoked when a request matches with the associated route. A hook method will be passed a request and a response object respectively. The methods you define need to be exported in order to be invoked at runtime.

Below, you can see an example:

In your API description file, set your method names as values to the hook keys.

# api.yaml
- path: /api/auth
  method: GET
  hook: token
- path: /api/users/:userid/status
  hook: status

Define and export functions in a JavaScript file.

// hooks.js
function token(request, response) {
    response.writeHead(200, { 'Content-Type': 'text/plain' });
    response.write(QxoXtkmYk5);
    response.end();
}

function status(request, response) {
    var authHeader = request.headers['Authorization'];
    if (authHeader !== 'Bearer QxoXtkmYk5') {
         response.writeHead(401);
    } else if (request.method === 'GET') {
         response.writeHead(200, { 'Content-Type': 'application/json' });
         response.write(JSON.stringify({ 'status': 'active' }));
    } 
    response.end();
}

exports.token = token;
exports.status = status;

Then, start a server passing hooks file as a parameter.

restdouble start -a api.yaml -j hooks.js

Use Query Strings

If you need dynamic behavior based on query strings, you can use a hook method.

// hooks.js
function getUsers(request, response) {
    var url = require('url');

    var query = url.parse(req.url, true).query;
    // now parameters can be accessed as properties of the 'query' object

    var data = [..];

    response.writeHead(200, { 'Content-Type': 'application/json' });
    response.write(JSON.stringify(data.slice(query.start, query.end)));
    response.end();
} 

exports.getUsers = getUsers;

Command Line Interface

Usage:

restdouble [options] 

Options:

-v, --version       output the version number
-a, --api [file]    give path to REST API description file
-j, --hooks [file]  give path to hook methods file
-H, --host [host]   set service host (default: "localhost")
-p, --port [port]   set service port (default: 3000)
-N, --nocors        disable CORS
-h, --help          output usage information

Docker

You can run restdouble as a Docker container.

To build a Docker image, at the root of the source tree, run:

docker build . -t restdouble

All input files needs to be mounted to the /usr/src/input/ folder in the container. The API description file has to be named as api.yaml, and the hooks module has to be named as hooks.js.

To run a container:

docker run -p 3000:3000 -v /Users/me/myinput/:/usr/src/input/ restdouble

License

MIT