Frontend Api Fframework is a library for cleaning up API calls in JavaScript frontend apps.
yarn add faffjs
# or
npm install --save faffjs
import FaffJS from 'faffjs';
const faff = new FaffJS();
export default faff; // Access your faff instance from anywhere in your app
Actions each represent a call to your API. They split the call into the request, error handling and success handling, although error and success handling are optional.
Requests are passed 2 arguments, the first is the context (more on this later) and the second is passed through from the dispatch call.
faff.add('signup', {
async request({ request }, { email, password }) {
await request('/api/signup', {
method: 'post',
data: {
email,
password,
},
});
},
});
Success and error functions are both passed the context parameter. The success
function is also passed the valid response. The error
functon is passed the
error object thrown by the request. Note that even though the error
function
returns a value, this will be thrown by the dispatch function (the promise
will reject).
faff.add('signup', {
async request({ request }, { email, password }) {
await request('/api/signup', {
method: 'post',
data: {
email,
password,
},
});
},
success(context, response) {
return response.data.message;
},
error(context, error) {
return error.response.data.errors;
},
});
For more complex requests, you may prefer using a controller. A controller will be instantiated for each request, allowing you to store state across the function calls.
Controller example:
import { FaffRequestController } from 'faffjs';
export default class YourController extends FaffRequestController {
async request(context, params) {
// your code
},
success(context, response) {
// your code
}
error(context, error) {
// your code
}
// other functions you need
}
And in your faff file:
import YourController from './YourController.js';
faff.add('your-request', YourController);
All action methods are called with a context. This is an instance of
FaffContext
which will be shared across the method calls. It provides access
to faff
methods and the raw response or error depending on the request:
FaffContext {
request // function
dispatch // function
params // any, params supplied to dispatch
faff // the faff instance
response? // response if the request was a success
error? // error if the request errored
}
Faff provides a request
function in the context. Using this will keep track of
the loading state, which can by accessed with faff.loading
. The request
function is otherwise a proxy to the requestAdapter
function. By defaut, this
is also just a proxy to fetch
, but this can be overridden to change the
request library you wish to use. E.g.:
import FaffJS from 'faffjs';
import axios from 'axios';
const faff = new FaffJS();
faff.requestAdapter = (...args) => axios(...args);
export default faff;
Faff provides a dispatch
function for dispatching API requests. This method
takes 2 parameters, the action name and the parameters which are passed directly
to the request.
import faff from './path/to/your/faff/instance';
await faff.dispatch('your-request', { your: 'data' });
This method always returns a promise. This promise will either resolve to the success value, or reject to the error value.
Faff provides an events API to watch the instance. These can be accessed via
faff.events
which follows the NodeJS event emitter API.
- beforeRequest
- afterRequest
- beforeSuccess
- afterSuccess
- beforeError
- afterError
Called before or after each method in an action. Is passed an object consisting of the action key, params and context.
- loadingUpdate
Called with the current number of loading requests. Can be used to update your apps loading state.
Full API spec can be seen here
You can install FaffJS directly into your Vuex Store as a namespaced module. To
do this you should instead import FaffVuex
which implements a toModule
method.
In your faff file:
import { FaffVuex } from 'faffjs';
const faff = new FaffVuex();
faff.add('foo', {
request(context) {
// You can access Vuex methods via context.store
},
});
export default faff;
In your store file:
import Vuex from 'vuex';
import faff from './path/to/your/faff';
export default new Vuex.Store({
modules: {
faff: faff.toModule(),
},
});
You can then use the actions directly from Vuex:
this.$store.dispatch('faff/foo', /* your params */);
Actions called via Vuex will have a store
included in the context
, which is
the Vuex action context.