Have ideas to improve npm?Join in the discussion! »

@tkrotoff/fetchTypeScript icon, indicating that this package has built-in type declarations

0.10.2 • Public • Published

@tkrotoff/fetch

npm version Node.js CI Codecov Bundle size Prettier Airbnb Code Style

A Fetch wrapper.

  • Simplifies the use of Fetch
  • Tiny
  • No dependencies
  • Fully tested
  • Written in TypeScript
  • Comes with test utilities

Why?

When using Fetch, you have to write some boilerplate:

const url = 'https://example.com/profile';
const data = { username: 'example' };

try {
  const response = await fetch(url, {
    method: 'POST',
    body: JSON.stringify(data),
    headers: {
      'content-type': 'application/json'
    }
  });
  if (!response.ok) {
    throw new Error('Network response was not ok');
  }
  const json = await response.json();
  console.log('Success:', json);
} catch (e) {
  console.error('Error:', e);
}

With @tkrotoff/fetch it becomes:

try {
  const response = await postJSON(url, data).json();
  console.log('Success:', response);
} catch (e /* HttpError | TypeError | DOMException */) {
  console.error('Error:', e);
}

You don't have to worry about:

  • HTTP headers: Accept and Content-Type are already set
  • stringifying the request body
  • One await instead of two
  • No need to manually throw an exception on HTTP error status (like 404 or 500)

Usage

Examples:

npm install @tkrotoff/fetch

import { defaults, postJSON } from '@tkrotoff/fetch';

defaults.init = { /* ... */ };

const response = await postJSON(
  'https://jsonplaceholder.typicode.com/posts',
  {
    title: 'foo',
    body: 'bar',
    userId: 1
  }
).json();
console.log(response);

Fetch is not supported by old browsers (IE), use whatwg-fetch polyfill + core-js for other modern JS features like async/await.

With Node.js use node-fetch polyfill.

API

  • get(input: RequestInfo, init?: RequestInit) => ResponsePromiseWithBodyMethods

  • postJSON(input: RequestInfo, body: Object, init?: RequestInit) => ResponsePromiseWithBodyMethods

  • post(input: RequestInfo, body: BodyInit, init?: RequestInit) => ResponsePromiseWithBodyMethods

  • putJSON(input: RequestInfo, body: Object, init?: RequestInit) => ResponsePromiseWithBodyMethods

  • put(input: RequestInfo, body: BodyInit, init?: Init) => ResponsePromiseWithBodyMethods

  • patchJSON(input: RequestInfo, body: Object, init?: RequestInit) => ResponsePromiseWithBodyMethods

  • patch(input: RequestInfo, body: BodyInit, init?: Init) => ResponsePromiseWithBodyMethods

  • del(input: RequestInfo, init?: RequestInit) => ResponsePromiseWithBodyMethods

ResponsePromiseWithBodyMethods being Promise<Response> with added methods from Body.

HttpError

@tkrotoff/fetch throws HttpError with a response property when the HTTP status code is < 200 or >= 300.

Test utilities

  • createResponsePromise(body?: BodyInit, init?: ResponseInit) => ResponsePromiseWithBodyMethods
  • createJSONResponsePromise(body: Object, init?: ResponseInit) => ResponsePromiseWithBodyMethods

HttpStatus

Instead of writing HTTP statuses as numbers 201, 403, 503... you can replace them with HttpStatus and write more explicit code:

import { HttpStatus } from '@tkrotoff/fetch';

console.log(HttpStatus._201_Created);
console.log(HttpStatus._403_Forbidden);
console.log(HttpStatus._503_ServiceUnavailable);

Configuration

@tkrotoff/fetch exposes defaults.init that will be applied to every request.

import { defaults } from '@tkrotoff/fetch';

defaults.init.mode = 'cors';
defaults.init.credentials = 'include';

Testing

When testing your code, use createResponsePromise() and createJSONResponsePromise():

import './mockFetch';

import * as Http from '@tkrotoff/fetch';

test('OK', async () => {
  const getSpy = jest.spyOn(Http, 'get').mockImplementation(() =>
    Http.createResponsePromise('test')
  );

  const response = await Http.get(url).text();
  expect(response).toEqual('test');

  expect(getSpy).toHaveBeenCalledTimes(1);
  expect(getSpy).toHaveBeenCalledWith(url);

  getSpy.mockRestore();
});

test('fail', async () => {
  const getSpy = jest.spyOn(Http, 'get').mockImplementation(() =>
    Http.createResponsePromise('<!DOCTYPE html><title>404</title>', {
      status: 404,
      statusText: 'Not Found'
    })
  );

  await expect(Http.get(url).text()).rejects.toThrow('Not Found');

  expect(getSpy).toHaveBeenCalledTimes(1);
  expect(getSpy).toHaveBeenCalledWith(url);

  getSpy.mockRestore();
});

Check examples/node and examples/web.

Install

npm i @tkrotoff/fetch

DownloadsWeekly Downloads

66

Version

0.10.2

License

MIT

Unpacked Size

50.4 kB

Total Files

23

Last publish

Collaborators

  • avatar