ApiMock is a minimal (0.5kb gzipped!) library for AngularJS that allows you to mock your RESTful API by routing your API calls to static JSON files.
The left shows the page where the API is missing. The right shows the same page, but API calls being rerouted to static JSON files.
Go to our website demo to try it out. That's the simplest way to understand.
Download it here or grab it through Bower.
bower install angular-apimock --save
Include angular-apimock.min.js
in your HTML:
<script src="/bower_components/angular-apimock/dist/angular-apimock.min.js"></script>
Add apiMock
as a dependency in your AngularJS app config (e.g. app.js
):
angular.module('myApp', ['apiMock']) ...
Now use $http
as usual. When you're looking at your webpage and want to use mock data, just add ?apimock=true
to the browser page URL. This way you never need to change your JavaScript!
You can also do individual overrides right in the config
object to $http
. E.g. $http( { url: '/...', method: GET, apiMock: true } )
.
If you want to design/test your error-handling then you can give a HTTP status code instead of true
. So ?apimock=401
will fail all requests with status code 401
(unauthorized). This is probably more useful on individual $http
requests.
You can also set it to automatically reroute API calls that fail. Just set the parameter to auto
(apimock=auto
in browser or $http call).
ApiMock appends the HTTP-verb before .json
so a GET-request to /api/customers/5
will be routed to /mock_data/customers/5.get.json
. Now just fill your /mock_data
directory with all the JSON files you want to grab.
ApiMock supports several operation modes. They're set globally and/or locally, where globally means on the browser URL and locally means in the $http request. There's only one parameter, apiMock
(case-insensitive).
Type: boolean/string/number
Default: undefined
Values:
true
: reroutes all requests
false
: turns off rerouting
auto
: will try the original request, if it fails then it tries to recover with a reroute
404
, 500
, etc: will reject all requests with the given HTTP status code
In the browser URL, just append ?apiMock=command
where command
is described above (true
, auto
, etc).
In the JavaScript, where you do the $http
request, the request object needs an attribute apiMock
with the value set to the command described above (true
, auto
, etc).
E.g.
$http({ method: 'GET', url: '...', apiMock: true });
ApiMock follows a simple concept: reroute HTTP requests, from apiPath
to mockDataPath
. So you can change the paths but any deeper configuration is probably easier to write your own httpInterceptor
(check the FAQ).
Configure is done through apiMockProvider.config()
. Add this to your AngularJS config file (e.g. app.js
):
.config(function (apiMockProvider) {
apiMockProvider.config({
mockDataPath: '/my_mock_data_path',
apiPath: '/my_api_path',
});
});
Type: string
Default: '/mock_data'
Set the path to be rerouted to.
Type: string
Default: '/api'
Set the path to be rerouted from.
Check the source code for our website demo. We're working on more demos. :)
Why not just use Interfake?
Interfake is a great complement to ApiMock. We assume you have a way to serve static JSON files. That can be because you're on a project with a server already set up and you can't do many changes to it but at least you can add static files. If you don't have that, then Interfake is a great way to set it up. Our idea is that the frontend JS doesn't change between calling the "real" API and the "fake" one.
Sometimes you don't have control over the API. It could be down for some reason, or it might not have been developed yet. ApiMock allows you as a frontend developer to continue working on the UI without changing any code. It's also helpful in figuring out what your API actually should have as you can play around with your static JSON and then have it serve the role as documentation for backend developers.
No, but it works in a similar fashion: it routes HTTP calls. Our initial implementation of apiMock used $httpBackend
but then it would route all AJAX requests and we only wanted to route API calls. A difference that's noticed when Angular tries to get HTML templates for directives, or if you try to load an image through AJAX. $httpBackend
is for unit testing, apiMock
is for the actual webpage.
Like disabling all network traffic yet things work? No, but it's a good idea. It would be perfect for presentation demo's when the WiFi is unreliable. If you have an idea of how to implement this, let us know!
Actually the basic idea here is to intercept http calls then do something that helps at design-time of the website. This project, angular-apimock
, aims to do that through rerouting API calls to static JSON files. We've experimented with making that flexible so you could configure it to do whatever you want, but that requires so much from this project and the core functionality (http interceptors) is so simple it's probably easier to create your own. If so, here's the basics:
angular.module('myModule', [])
.config(function ($httpProvider) {
$httpProvider.interceptors.push('yourHttpInterceptor');
})
.service('yourHttpInterceptor', function($q) {
this.request = function (req) {
if (req) {
// Do whatever you want to the request here.
}
return req || $q.when(req);
};
});
This blog post is pretty good at diving deeper into this.
- Demo based on Magic The Gathering cards (reference to a //build presentation)
- Demo for checking mock-flag
- Demo with Interfake
- Handle queries (?search=banana), not just ignore them
- Handle body data in POST requests?
- HTTP response overrides (200?) shouldn't always go to $http.error()
- Test
apimock=true
in more scenarios - Remember mock-mode after page navigation
- Plunkr demos
- Visual queue that mock is happening. Maybe also $log?
- Work with $resource (maybe it does already?)
ApiMock started as a concept at a large eCommerce project years ago. Having the backend team completely separate from the frontend team created some constraints that needed to be solved. Now it's been cleaned up and simplified for AngularJS. We'd love any feedback so feel free to raise an issue or do a pull request (make sure you run grunt
). If you want to implement something from the Wishlist, that would be awesome too!