• Stars
    star
    331
  • Rank 127,323 (Top 3 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 10 years ago
  • Updated about 8 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

API mocking for the client side JavaScript applications

APItizer

APItizer is a library that allows you to mock APIs for browser applications with JSON schema. JSON schema is usually used to validate responses from APIs, but APItizer adds the ability to generate data from the same structure.

APItizer requires understanding of the JSON schema syntax and I can recommend this guide to get you started.

Updating from v0.0.4

You must call apitizer.start() now for APItizer to work.

Prior to the version 0.1.0 APItizer was using the can.fixture library to mock the XHR requests, but it was replaced with the FakeXMLHttpRequest library. FakeXMLHttpRequest library replaces the browser XHR object which enables APItizer to work without any library dependencies (jQuery or Zepto).

This change requires you to manually start the APItizer from your code with the following command:

apitizer.start();

This will replace the window.XMLHttpRequest object and allow APItizer to take over. Stopping APItizer is done with the following command:

apitizer.stop();

Why

When developing single page apps, it is beneficial to develop the frontend and the backend in the parallel. To achieve that, you need to mock the API. APItizer allows you to mock your API by defining the JSON schema which is used to generate the fake data.

By using the JSON schema to define the format of the API responses, you create an explict contract which can be used to validate backend responeses once you start to integrate the real API.

Installation

Install it with bower:

bower install apitizer

APItizer can used included either as a script tag:

<script type="text/javascript" src="path/to/apitizer.js"></script>

Or loaded with the Require.js (or any other AMD loader):

define(["path/to/apitizer"], function(apitizer){ })

After the APItizer is loaded you have to start it before it can intercept the requests:

define(["path/to/apitizer"], function(apitizer){ 
	apitizer.start();
})

Example

Let's implement a simple user endpoint. It will reside on the /users endpoint and implement all the usual REST operations.

First let's define the schema:

var schema = {
	type : "object",
	properties : {
		id : {
			type : "integer"
		},
		username : {
			type : "string"
		},
		password : {
			type : "string"
		}
	}
}

Now we can add it to the APItizer:

apitizer.addSchema('user', schema);

After adding it to the apitizer we can mock the API:

apitizer.fixture.resource('/users', apitizer.schemaStore('user', 10));

This will create a store with 10 users in it and add all REST API endpoints:

GET /users
GET /users/{id}
POST /users
PUT /users/{id}
DELETE /users/{id}

Now you can normally use AJAX functions and they will hit the mocked API:

$.get('/users') // Response will return 10 users
$.get('/users/1') // Response will return the user with the id 1
$.post('/users', {username : 'foo', password : 'bar'}) // User will be created and saved to the store
$.ajax('/users/1', {type : 'put', data : {username : 'baz'}}) // User with the id 1 will be updated
$.ajax('/users/1', {type : 'delete'}) // User with the id 1 will be destroyed and removed from the store

Overriding generators

APItizer implements it's own generators for all types supported by the JSON schema, but sometimes you want more control over the data that is being generated. To achieve this, you can pass overrides to the store:

var store = apitizer.schemaStore('user', 10, {
	id : apitizer.types.autoincrement(),
	username : function(){
		var count = 1;
		return function(){
			return "User " + (count++);
		}
	}
});

This store will now contain objects that look like this:

[{
	id: 1,
	username : "User 1",
	password : ...
},
{
	id: 2,
	username : "User 2",
	password : ...
}]

Using overrides will allow you to take control over parts of your data that are important to you. Another use for the overrides is embedding an object from one store to the object generated from another store.

Let's say you want to mock a simple publishing API, where you have two types of resources:

  1. Articles
  2. Authors

Each article contains the author object. You can easilly write a schema for this:

var authorSchema = {
	type : "object",
	properties : {
		id : {
			type : "integer"
		},
		username : {
			type : "string"
		},
		password : {
			type : "string"
		}
	}
}

var articleSchema = {
	type : "object",
	properties : {
		title : {
			type : "string"
		},
		body : {
			type : "string"
		},
		author : {
			$ref : "author"
		}
	}
}

apitizer.addSchema('author', authorSchema);
apitizer.addSchema('article', articleSchema);

This example introduces another concept, referenced schemas which are denoted by the $ref key. For now, it is enough to know that this will get the author schema from the repository and use it to generate the data.

If we create author and article stores without overrides:

var authorStore = apitizer.schemaStore('author', 10);
var articleStore = apitizer.schemaStore('article', 10);

Each article will contain generated author object, but that author object will not look like anything contained in the authorStore. We can fix that by using overrides:

var authorStore = apitizer.schemaStore('author', 10);
var articleStore = apitizer.schemaStore('article', 10, {
	author : authorStore.one()
});

In this case authorStore.one() will return a random object from the store, and that object will be embedded in the author property of the article.

Custom data and API endpoints

In some cases you might need additional API points that can handle some specific task. For instance you might have /login endpoint where users can login. This action will still use the users store, but will have to behave differently than the default REST actions. Also, for development and testing you need a user with the known credentials, so you can actually login to the app. Here is how you can solve this problem with APItizer:

var schema = {
	type : "object",
	properties : {
		id : {
			type : "integer"
		},
		username : {
			type : "string"
		},
		password : {
			type : "string"
		}
	}
}, userStore;

apitizer.addSchema('user', schema);
userStore = apitizer.schemaStore('user', 0, {
	id : apitizer.types.autoincrement()
})

Here we have defined the schema, and created an empty store, now we can add some custom data:

userStore.add({
	username : 'retro',
	password : '1337'
});

This will create a user with known credentials. Now all we need to do is create the /login endpoint:

apitizer.fixture('POST /login', function(params){
	var users = userStore.db(params) // Search the data in the store's database
	if(users.count() === 0){
		throw {errors: ['Wrong credentials'], status: 401}
	} else {
		return users.first();
	}
});

APItizer uses the excellent TaffyDB library to store the data, so you can use it's fancy querying possibilities to get the data.

Now you can emulate the login process by POSTing to the /login endpoint:

$.post('/login', {
	username : 'retro',
	password : 1338
}).then(function(user){
	alert('You logged in!')
}, function(error){
	alert('Wrong credentials!')
});

Response delay

To simulate the real requests, responses will be returned with a delay. Default delay is 200 milliseconds, but you can easiliy change it:

apitizer.fixture.delay(300) // delay is now 300 milliseconds

You can also give it a range of values, which will make the delay random:

apitizer.fixture.delay(200, 500) // delay will be between 200 and 500 milliseconds

Random delay is a good way to simulate the real network conditions, and to get a feeling of responsivnes of your app.

--

You can find more docs in the wiki

More Repositories

1

graphql-builder

GraphQL client library for Clojure and ClojureScript
Clojure
184
star
2

penkala

Composable query builder for PostgreSQL written in Clojure.
PLpgSQL
100
star
3

state-machete

Functional statecharts implementation for Clojure and ClojureScript.
Clojure
33
star
4

color_namer

Color Namer enables you to name color from HTML hash or RGB value
Ruby
19
star
5

gridfs-rackdav

GridFS resource for RackDAV
Ruby
18
star
6

generator-canjs

Yeoman generator for CanJS
JavaScript
15
star
7

Tonfa.js

Tonfa.js is a glue library between CanJS and jQueryMobile
JavaScript
11
star
8

cucumber-funcunit

Example of Cucumber + FuncUnit
CSS
10
star
9

keechma-next-realworld-app

Clojure
8
star
10

FormBinder

Form builder for JavaScriptMVC with automatic binding to a model
JavaScript
8
star
11

canjs-workshop

CSS
7
star
12

konserve-pg

PostgreSQL driver for Konserve
Clojure
7
star
13

can-form

Form Library for CanJS
JavaScript
5
star
14

writisan

CSS
4
star
15

tasquencer

TypeScript
4
star
16

canjs-uploader

Example file uploader can.Component with jQuery-file-upload
JavaScript
4
star
17

can-turbomodel

JavaScript
4
star
18

forms-validations

Clojure
3
star
19

protok-backend

Clojure
3
star
20

protok-frontend

Clojure
3
star
21

require-can-renderers

CanJS view renderers for the Require.js
JavaScript
3
star
22

mongoid_nested_fields

MongoidNestedFields allows you to handle complex data structures in one field in MongoDB
Ruby
3
star
23

javascript-object-validator

Validation of Javascript objects based on system simmilar to Rails ActiveRecord validation.
JavaScript
3
star
24

gen-ui-experiments

TypeScript
3
star
25

content-store

Clojure
2
star
26

kekomi-cms

JavaScript
2
star
27

confeedence

WhenHub Hackathon App
Clojure
2
star
28

garden-basscss

Port of BassCSS library to Garden
Clojure
2
star
29

estimator

TypeScript
1
star
30

keechma-entanglement

Clojure
1
star
31

ey-cloud-recipes

A starter repo for custom chef recipes on EY's cloud platform
Ruby
1
star
32

hibreed-frontend

1
star
33

can-chat

CanJS Frontend for KiwiIRC
1
star
34

steal-ts

JavaScript
1
star
35

firecan

JavaScript
1
star
36

kekomi_content_types

Ruby
1
star
37

effect-remix

TypeScript
1
star
38

HibreedCMS

CMS based on Rails and MongoDB
JavaScript
1
star
39

keechma-next-state-machete

Clojure
1
star
40

kekomi-file-manager

Filemanager implemented with the JavaScriptMVC. Part of the KekomiCMS
1
star
41

Rails-3-inline-form

Rails 3 inline forms with formtastic and jQuery
Ruby
1
star
42

canjs-app

Example app structure with CanJS and Yeoman
CSS
1
star
43

graphql-schema-compare

JavaScript
1
star
44

Comicbox

Comic book reader based on Sinatra and JavaScriptMVC
JavaScript
1
star
45

manually-call-dataloader-example

JavaScript
1
star
46

old-kekomi-client

UI part of the Kekomi CMS. Very WIP.
JavaScript
1
star