fetch-factory
v0.2.1
Published
A wrapper around the new `fetch` API to make creating services to talk to APIs easier.
Readme
fetch-factory
A wrapper around the new fetch API to make creating services to talk to APIs easier.
## Example
var fetchFactory = require('fetch-factory');
var Users = fetchFactory.create({
url: 'http://api.mysite.com/users/:id',
}, {
find: { method: 'GET' },
create: { method: 'POST' },
});
Users.find(); // GET /users
Users.find({
params: { id: 123 },
}); // GET /users/123
Users.create({
data: {
name: 'Jack',
},
}); // POST /users with JSON stringified obj { name: 'jack' }Install
npm install fetch-factoryConsumable in the client through jspm, Webpack or Browserify.
You can also grab dist/fetch-factory.js or dist/fetch-factory.min.js which is a browser build. It exposes global.fetchFactory. example/index.html shows how you would use this.
Note that this library assumes a global fetch and Promise object. If you need to polyfill these, the following are recommended:
- github/fetch
window.fetchpolyfill - jakearchibald/es6-promise
Promisepolyfill.
Configuration
Configuration for a particular request can be set in one of three places:
- in the config object that's the first argument to
fetchFactory.create - in an object that you pass when telling fetch-factory what methods to create
- in the call to the method that fetch factory created
Configuration set further down the chain will override configuration set previously. For example:
var UserFactory = fetchFactory.create({
url: 'http://api.mysite.com/users/:id',
method: 'GET',
}, {
find: {},
create: { method: 'POST' },
});When UserFactory.find is called, it will make a GET request, because the default configuration for UserFactory was given method: 'GET'. However, when UserFactory.create is called, it will make a POST request, because configuration was passed that is specific to that method. Although in reality you never need to, you could call UserFactory.find({ method: 'POST' }), which would cause the find method to make a POST request that time, because configuration passed in when a method is invoked overrides any set before it.
POST Requests
When a method defined by fetch-factory makes a POST request, it assumes that you'd like to POST JSON and sets some extra configuration:
- the
Acceptheader of the request is set toapplication/json - the
Content-Typeheader of the request is set toapplication/json - if you pass in a
dataparameter, that is converted into JSON and sent as the body of the request
Shortcut Methods
There's a few methods that we've come to use often with our factories: find, create and update. fetch-factory comes with these definitions by default, so you can just tell it which ones you'd like to create:
var UserFactory = fetchFactory.create({
url: '/users/:id',
methods: ['find', 'create'],
});Interceptors
fetch-factory also supports the concept of interceptors that can take a request and manipulate it before passing it on.
Request Interceptors
If you need to apply a transformation to every request before it is made (for example, adding an authorisation header), you can use a request interceptor. These can be sync or async. You can define a single request interceptor, or an array of multiple. An interceptor is expected to return the modified request object, or a new object with three properties:
headers: an object of key value pairs mapping headers to valuesbody: the string representing the request body, ornull.method: the method of the request
var UserFactory = fetchFactory.create({
url: 'http://api.mysite.com/users/:id',
method: 'GET',
interceptors: {
request: function(request) {
request.headers['Authorisation']: 'Bearer ACCESS_TOKEN123';
return request;
},
},
}, {
find: {},
});
UserFactory.find().then(function(data) {
console.log(data.name) // 'bob'
});By using an interceptor in this way you can avoid repeating the authorisation logic accross your frontend code base.
Response Interceptors
By default, fetch-factory will call its default response interceptor, which simply takes the stream returned by fetch and consumes it as JSON, returning a JavaScript object. You can override this by passing an interceptors object with a response key:
var UserFactory = fetchFactory.create({
url: 'http://api.mysite.com/users/:id',
method: 'GET',
interceptors: {
response: function(data) {
return { name: 'bob' };
},
},
}, {
find: {},
});
UserFactory.find().then(function(data) {
console.log(data.name) // 'bob'
});A time when you might want to override the default response interceptor is if you need access to extra information on the response, such as headers. In this case fetch-factory's default interceptor will be insufficient, and you should override it to simply pass the full request through:
var UserFactory = fetchFactory.create({
url: 'http://api.mysite.com/users/:id',
method: 'GET',
interceptors: {
response: function(response) { return response; },
},
}, {
find: {},
});
UserFactory.find().then(function(response) {
console.log(response.headers.get('Content-Type'));
});Changelog
V0.2.1 - 8/12/2015
- fix issue that lead to port numbers in URLs not working - thanks @copyhold
V0.2.0 - 8/12/2015
- fix isssue that lead to being unable to create more than one factory
V0.1.0 - 11/11/2015
- first release
