basicallydan / interfake

:computer: Fake APIs for prototypes & automated tests.
Other
805 stars 39 forks source link

Interfake: Quick JSON APIs

Gitter

Interfake is a tool which allows developers of client-side applications of any platform to easily create dummy HTTP APIs to develop against. Let's get started with a simple example.

Get started

If you don't want to use the JavaScript method to create your Interfake API, go read up on all the methods. Otherwise, read on.

Install Interfake in your project.

npm install interfake --save

Let's write a simple fake API:

var Interfake = require('interfake');
var interfake = new Interfake();
interfake.get('/whats-next').body({ next : 'more stuff '});
interfake.listen(3000); // The server will listen on port 3000

Now go to http://localhost:3000/whats-next in your browser (or curl), and you will see the following:

{
    "next":"more stuff"
}

You can also chain response properties:

var Interfake = require('interfake');
var interfake = new Interfake();
interfake.get('/whats-next').status(400).body({ error : 'such a bad request'});
interfake.listen(3000);

/*
# Request:
$ curl http://localhost:3000/whats-next -X GET
# Response:
400
{
    "error":"such a bad request"
}
*/

You can use different HTTP methods:

var Interfake = require('interfake');
var interfake = new Interfake();
interfake.post('/next-items').status(201).body({ created : true });
interfake.listen(3000);

/*
# Request:
$ curl http://localhost:3000/next-items -X POST
# Response:
201
{
    "created":true
}
*/

You can specify endpoints which should only be created once other ones have been hit.

var Interfake = require('interfake');
var interfake = new Interfake();
var postResponse = interfake.post('/next-items').status(201).body({ created : true });
postResponse.creates.get('/items/1').status(200).body({ id: 1, name: 'Item 1' });
postResponse.creates.get('/next-items').status(200).body({ items: [ { id: 1, name: 'Item 1' } ] });
interfake.listen(3000);

/*
# Request:
$ curl http://localhost:3000/next-items -X POST
# Response:
201
{
    "created":true
}

# Request:
$ curl http://localhost:3000/items/1 -X GET
# Response:
200
{
    "id":1
    "name":"Item 1"
}
*/

You can even specify how endpoints should be extended once others have been hit.

var Interfake = require('interfake');
var interfake = new Interfake();
interfake.get('/items').status(200).body({ items: [ { id: 1, name: 'Item 1' } ] });
interfake.get('/items/1').status(200).body({ id: 1, name: 'Item 1' });
var postResponse = interfake.post('/items').status(201).body({ created : true });
postResponse.creates.get('/items/2').status(200).body({ id: 2, name: 'Item 2' });
postResponse.extends.get('/items').status(200).body({ items: [ { id: 2, name: 'Item 2' } ] });
interfake.listen(3000);

/*
# Request:
$ curl http://localhost:3000/items -X GET
# Response:
200
{
    "items" : [
        {
            "id":1
            "name":"Item 1"
        }
    ]
}

# Request:
$ curl http://localhost:3000/items -X POST
# Response:
201
{
    "created":true
}

# Request:
$ curl http://localhost:3000/items -X GET
# Response:
200
{
    "items" : [
        {
            "id":1
            "name":"Item 1"
        },
        {
            "id":2
            "name":"Item 2"
        }
    ]
}
*/

There's more options, though, including delays, custom response headers, and handling query string parameters.


API

The majority of Interfake users will probably be interested in the JavaScript API, which is covered below. However, there are in fact three ways to use Interfake: JavaScript, on the Command Line (using static JSON files), or using an HTTP meta-API. These are covered in detail in the Wiki.

JavaScript

Fluent Interface

JSONP

Interfake supports JSONP. Just put ?callback on the end of the URLs being called.

$ curl http://localhost:3000/whattimeisit?callback=handleSomeJson

Use Cases

Backend/API Prototype for a Single-Page Application (SPA)

By using Interfake's .serveStatic() method, you can serve some front-end HTML, JavaScript and CSS which uses the API you've created as the backend. Not only does this massively speed up development time by not having to have a real API, it serves as a great prototype for the real API, and avoids having to mock requests. This is my most common use for Interfake.

Backend for a Mobile Application

If you'd like to develop an API-driven mobile application you might not yet have a finished API available. This is a perfect example of where Interfake is useful. You can quickly mock up some dummy APIs and work on the mobile application. In parallel, perhaps another developer will be creating the real API, or you could create it later.

Automated Testing

You can use Interfake to create dummy APIs which use data from your test setup with the HTTP method above, or by using a static set of test data. If you're writing your test suite using a NodeJS library, you can use the JavaScript API.

The HTTP API is particularly useful for developing iOS Applications which uses Automated tests written in JavaScript, or developing Node.js applications which rely on external APIs.

For an example of how to do this, please see the web page test example.

Regular Expressions for URLs

Regular expressions can be used to specify endpoint URLs in two different ways depending on which interface you use. For the fluent API, you simply put a JavaScript regular expression as the URL, e.g.

interfake.get(/\/regular\/expression/).status(200);

This is also supported when using createRoute, but since JSON does not support regular expressions, a different method must be used here:

[
    {
        "request": {
            "url": {
                "pattern" : "/what/the/.*",
                "regexp" : true
            },
            "method": "get"
        },
        "response": {
            "code": 200
        }
    }
]

The pattern specified in the request.url.pattern string will be parsed and treated as a regular expression.

Proxying another API

There are a number of reasons you might want to proxy another API. Three of the more common ones are:

Interfake allows you to proxy another URL quite easily and also specify any headers you like while doing so, using the proxy option.

interfake.get('/github-issues').proxy('https://api.github.com/repos/basicallydan/interfake/tags');

The example above creates a simple proxy against the URL https://api.github.com/repos/basicallydan/interfake/tags and will return whatever a public, non-authorized user will see. However, consider an endpoint which requires authorization.

interfake.get('/github-issues').proxy({
    url: 'https://api.github.com/repos/basicallydan/interfake/tags',
    headers: {
        'Authorization': 'Token qoinfiu13jfcikwkhf1od091dj0'
    }
});

This example uses an authorization token to authorize the request. This is one of the common use-cases. However, the first one will easily solve CORS issues, and any other headers apart from Authorization can be specified instead.

Echoing the request body

This can be easily achieved using the .echo() method in the fluent interface, or by specifying the following for route options:

{
    request : {
        url : '/echo',
        method: 'post'
    },
    response : {
        echo : true 
    }
}

A request to the /echo endpint will return whatever body it is sent. You can see more examples of this in the examples folder.

Creating a static API

If you have a website or mobile application which only needs static data, deploy Interfake to a server somewhere with a JSON file serving up the data, and point your application at it.

Compatibility

I tested this on my Mac. If you have trouble on Windows or any other platform, raise an issue.

Version History

Contribute

Interfake is a labour of love, created for front-end and mobile developers to increase their prototyping and development speeds. If you can contribute by getting through some issues, I would be very grateful. Please read more about how to contribute in the CONTRIBUTING.md document.

It's important that the tests all pass so we can keep this little badge green:

Travis

<3 Open Source!

I Love Open Source

Dependencies

Works well with

Thank yous

Alun for reading this readme.

Author & Contributors

Future work