Using Frest

After installation, import it your code. The Frest class is exported in default namespace

1
import Frest from 'frest';

The Frest Instance

Now we can create an instance to communicate with an API URL. Suppose we want to call an API with base URL https://api.example.com

1
const api = new Frest('https://api.example.com');

If you are using the UMD build through a script tag, Frest class is available in global window and self object.

We can also configure the instance with some default parameter, which will be applied to all API call. In this example, we want all request to append a header X-Foo with value bar

123456
const api = new Frest({
  base: 'https://api.example.com',
  headers: new Headers({
    'X-Foo': 'bar',
  }),
});

The configuration object generally extends fetch init parameter. Refer to Configuration page for more information of available properties

Calling API Endpoint

With the instance configured, we can now use its methods to call an API endpoint. With native fetch you have to provide {method: '<HTTP METHOD>'} to call endpoint with certain HTTP Method. In Frest it’s available directly as method in the instance.

Here we want to call GET https://api.example.com/foo.

1
api.get('foo').then(/*Do something with the response*/);

As with the native Fetch API, Frest also needs Promise to be available in the browser. If there is a browser of your target that doesn’t support Promise, you need to include a polyfill before importing Frest, e.g. es6-promise.

Here is other available method of the instance, all correspond to HTTP Method as the name implies.

 1 2 3 4 5 6 7 8 91011
api.post(...) // HTTP POST
api.create(...) // alias of api.post
api.read(...) // alias of api.get
api.put(...) // HTTP PUT
api.update(...) // alias of api.put
api.delete(...) // HTTP DELETE
api.destroy(...) // alias of api.delete
api.patch(...) // HTTP PATCH
api.option(...) // HTTP OPTION
api.download(...) // Download file, support onDownloadProgress event
api.upload(...) // Upload file, support onUploadProgress event

We can provide specific configuration to each request. It’ll be merged with the default configuration we specified in the instance. Here we set the X-Foo header for this specific request with foo value.

123
api
  .get('foo', { headers: new Headers({ 'X-Foo': 'foo' }) })
  .then(/*Do something with the response*/);

Response Processing

When the request is finished, the promise will be completed and we can do something with the response.
The resolved value is an object of IResponse interface, contains origin property which is the original fetch Response, and the body if any.
If there is any error during the request, we can catch it in the chain. The error is an instance of FrestError.

 1 2 3 4 5 6 7 8 910111213141516
api
  .get('foo', { headers: new Headers({ 'X-Foo': 'foo' }) })
  .then(res => {
    const { origin, body } = res;
    console.log('origin', origin);
    console.log('body', body);
    // We can safely omit the origin.ok check because Frest took care of it.
    // If origin.ok is false, it'll be thrown as an error and caught in the catch block below
    return origin.json();
  })
  .then(body => {
    console.log('body', body);
  })
  .catch(err => {
    console.error('request failed', err);
  });

The body property above by default is undefined. It’s meant for response interceptors to process and put value in there.
For example, the above task of parsing application/json response can be repetitive and a suitable candidate to put in a response interceptor.
In fact, there is frest-json, an official interceptor package of Frest that do just that.

Find out more about Interceptor Concept here.

Async Await Style

We can also use Frest api calling in async-await fashion.

 1 2 3 4 5 6 7 8 91011
async function makeRequest() {
  try {
    const {origin} = await api.post('blah');
    if (origin.ok) {
      const body = await origin.json();
      console.log('body', body);
    }
  } catch (err) {
    console.error('request failed', err);
  }
}

Using TypeScript

Frest is developed with TypeScript and include its own definition files. We can comfortably import Frest and use the awesomeness of TypeScript altogether :)