⭐️ bestfetch

Making Requests

This guide will cover how to configure requests as well as how to handle the responses that you receive.

To begin, import the bestfetch function:

import { bestfetch } from 'bestfetch';

Configuring Requests

bestfetch supports all of the same options as fetch.

In fact, because bestfetch is a lightweight wrapper around fetch, it can be beneficial for you to be familiar with that API. If you're new to fetch, you may wish to read the Using Fetch guide on MDN.

Specifying the URL

You can pass a URL as the first argument, or you can pass an options object and specify the URL there. URLs can be both absolute or relative.

bestfetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(handleResponse);

bestfetch({
  url: '/api/books/2'
})
  .then(handleResponse);

Specifying the HTTP Method

Pass the method option. For instance, to make a POST request:

bestfetch('https://jsonplaceholder.typicode.com/todos/1', {
  method: 'post'
})
  .then(handleResponse);

The method option is case-insensitive, so either "POST" and "post" will work.

Sending Data in the Request Body

Use the body option to send data to the server. To do this, stringify your data and pass the correct headers so that the server knows how to parse the data:

bestfetch('https://jsonplaceholder.typicode.com/todos/1', {
  method: 'post',
  body: JSON.stringify(data),
  headers: {
    'Content-Type': 'application/json'
  }
})
  .then(handleResponse);

Sending Query Parameters

Include query parameters in the url.

bestfetch('/api/books?sort=author')
  .then(handleResponse);

You may find it preferable to use a library that stringifies query parameters from an object. The following example shows how you can use bestfetch with query-string:

import queryString from 'query-string';

const qs = queryString.stringify({ sort: 'author' });

bestfetch(`/api/books?${qs}`)
  .then(handleResponse);

Configuring the Caching Behavior

bestfetch will intelligently cache your responses to reduce network requests. Refer to the guide on Caching Responses to learn how to configure this behavior.

Other Options

bestfetch supports all of the same options as fetch, including:

  • method
  • headers
  • body
  • mode
  • credentials
  • cache (note: this is unrelated to the caching system of bestfetch)
  • redirect
  • referrer
  • referrerPolicy
  • integrity
  • keepalive
  • signal

So far, this guide has covered the most commonly-used options. For more information on these other options, refer to the fetch() documentation on MDN.

In addition to the options that come from fetch, there are additional options introduced in bestfetch. These are used for the caching and deduplication features.

  • cachePolicy: Controls the caching behavior. Learn more in the caching guide.
  • dedupe: Whether or not to dedupe this request. Learn more in the deduplication guide.
  • responseType. Use this option when making requests to endpoints that do not return JSON. Learn more here.
  • requestKey. An advanced option that is used to determine which requests are identical. You probably won't need this. Learn more in the deduplication guide.

Receiving Responses

bestfetch returns a Promise. This Promise resolves if a response from the server or cache is received, and it rejects otherwise.

Successful Respones

When a response is successful you can access the data from the response on res.data.

bestfetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(res => {
    console.log('Got the data', res.data);
  });

Errors

If the server replies with an error response, then the Promise will still resolve. This is important to note, because it may be unexpected.

If your server returns HTTP status codes that are greater than or equal to 400 when there are errors, then you can check for server errors with the following code:

bestfetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(res => {
    if (res.ok) {
      console.log('The request was successful');
    } else {
      console.log('The request was unsuccessful.');
    }
  });

If no response is received, then the promise will reject.

bestfetch('https://jsonplaceholder.typicode.com/todos/1')
  .catch(err => {
    console.log('Another kind of error occurred.', err);
  });

The Promise will also reject with a CacheMissError if the cachePolicy of the request is set to "cache-only" and nothing was found in the cache.

bestfetch('https://jsonplaceholder.typicode.com/todos/1', {
  cachePolicy: 'cache-only'
})
  .catch(err => {
    if (err instanceof CacheMissError) {
      console.log('This request did not have a response in the cache.');
    }
  });

Trying It Out

This webpage has bestfetch available on the window for you to use. You can try it out by making requests to the JSON Placeholder API.

Here are a few examples to get you started.

Fetching a Resource

bestfetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(res => {
    console.log('Got the todo', res.data);
  });

Creating a Resource

bestfetch('https://jsonplaceholder.typicode.com/posts', {
    method: 'post',
    body: JSON.stringify({
      title: 'My first post',
      body: 'This is a draft post.',
      userId: 1
    }),
    headers: {
      "Content-type": "application/json; charset=UTF-8"
    }
  })
  .then(res => console.log('Created:', res.data));

Updating a Resource

bestfetch('https://jsonplaceholder.typicode.com/posts/1', {
    method: 'put',
    body: JSON.stringify({
      id: 1,
      title: 'foo',
      body: 'bar',
      userId: 1
    }),
    headers: {
      "Content-type": "application/json; charset=UTF-8"
    }
  })
  .then(res => console.log('Updated:', res.data));

Deleting a Resource

bestfetch('https://jsonplaceholder.typicode.com/posts/1', {
  method: 'delete'
})

Other Examples

Check out the JSON Placeholder examples for more inspiration.