Giter VIP home page Giter VIP logo

httpclient's Introduction

HttpClient

Typed wrapper around axios.

Github - Action NPM Package Code Coverage Sonar Violations

This package's API is still developing and will not follow SEMVER until release 1.0.0.

HttpClient helps standardarize making HTTP calls and handling when errors are thrown. HttpClient works both in the browser and node environments. Exposes an interface to abort HTTP calls using AbortController. See below about using AbortController in older environments. Exposes an interface to control how requests and responses are handled. See below about using HttpClient's Request Strategies. Some strategies are provided in this package, but you can also implement your own strategies. List of strategies are provided below.

Installation

npm install @seriouslag/httpclient

Example

To see additional examples look in the `src/examples/` directory.

Basic example:

import { HttpClient } from '@seriouslag/httpclient';

interface NamedLink {
  name: string;
  url: string;
}

interface PokemonPage {
  count: number;
  next: string|null;
  previous: string|null;
  results: NamedLink[];
}

const httpClient = new HttpClient();

async function fetchPokemonPage (offset: number = 0, pageSize: number = 20) {
  const pokemonApiUrl = 'https://pokeapi.co/api/v2';
  return await this.httpClient.get<PokemonPage>(`${pokemonApiUrl}/pokemon`, {
      params: {
        offset: offset,
        limit: pageSize,
      },
  });
}

// IIFE
(async () => {
  const results = await fetchPokemonPage(0, 100);
  console.log(results);
})();

Configuring axios

Axios can be configured, axios options can be passed into the constructor of HttpClient.

import { HttpClient } from '@seriouslag/httpclient';
import { Agent } from 'https';

const httpsAgent = new Agent({
  rejectUnauthorized: false,
});

const httpClient = new HttpClient({
  axiosOptions: {
    httpsAgent,
  },
});

Using AbortController

Each of the HTTP methods of the HttpClient accept an instance of a AbortController. This allows HTTP requests to be cancelled if not already resolved.

import { HttpClient } from '@seriouslag/httpclient';

interface PokemonPage {
  count: number;
  next: string|null;
  previous: string|null;
  results: NamedLink[];
}

const pokemonApiUrl = 'https://pokeapi.co/api/v2';
const httpClient = new HttpClient();
const cancelToken = new AbortController();

const request = httpClient.get<PokemonPage>(`${pokemonApiUrl}/pokemon`, cancelToken);

cancelToken.abort();

try {
  const result = await request;
  console.log('Expect to not get here because request was aborted.', result)
} catch (e) {
  console.log('Expect to reach here because request was aborted.')
}

AbortController in older environments

Abort controller is native to node 15+ and modern browsers. If support is needed for older browsers/node versions then polyfills can be found. This polyfill is used in the Jest test environment for this repository: abortcontroller-polyfill

import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only';
import { HttpClient } from '@seriouslag/httpclient';

const httpClient = new HttpClient();

Using Request Strategies

A request strategy is middleware to handle how requests are made and how responses are handled. This is exposed to the consumer using the `HttpRequestStrategy` interface. A request strategy can be passed into the HttpClient (it will be defaulted if not) or it can be passed into each request (if not provided then the strategy provided by the HttpClient will be used). A custom strategy can be provided to the HttpClient's constructor.

Provided strategies:

  • DefaultHttpRequestStrategy - Throws when a response's status is not 2XX
  • ExponentialBackoffRequestStrategy - Retries requests with a backoff. Throws when a response's status is not 2XX
  • MaxRetryHttpRequestStrategy - Retries requests. Throws when a response's status is not 2XX
  • TimeoutHttpRequestStrategy - Requests have are canceled if a request takes longer then provided timeout. Throws when a response's status is not 2XX

Using Request Strategy in the constructor

The following code creates an instance of the HttpClient with a custom HttpRequestStrategy, all requests will now use this strategy by default.

import { HttpClient, HttpRequestStrategy } from '@seriouslag/httpclient';

class CreatedHttpRequestStrategy implements HttpRequestStrategy {

  /** Passthrough request to axios and check response is created status */
  public async request<T = unknown> (client: AxiosInstance, axiosConfig: AxiosRequestConfig) {
    const response = await client.request<T>(axiosConfig);
    this.checkResponseStatus<T>(response);
    return response;
  }

  /** Validates the HTTP response is successful created status or throws an error */
  private checkResponseStatus<T = unknown> (response: HttpResponse<T>): HttpResponse<T> {
    const isCreatedResponse = response.status === 201;
    if (isCreatedResponse) {
     return response;
    }
    throw response;
  }
}

const httpRequestStrategy = new CreatedHttpRequestStrategy();

// all requests will now throw unless they return an HTTP response with a status of 201
const httpClient = new HttpClient({
  httpRequestStrategy,
});

Using Request Strategy in a request

The following code creates an instance of the HttpClient with a provided HttpRequestStrategy (MaxRetryHttpRequestStrategy), then starts a request and passes a different strategy (DefaultHttpRequestStrategy) to the request. The request will now used the strategy provided instead of the HttpClients strategy.

import { HttpClient, DefaultHttpRequestStrategy, MaxRetryHttpRequestStrategy } from '@seriouslag/httpclient';

const httpClient = new HttpClient({
 httpRequestStrategy: new MaxRetryHttpRequestStrategy(10),
});

// IIFE
(async () => {
 const response = await httpClient.get('/endpoint', {
   httpRequestStrategy: new DefaultHttpRequestStrategy(),
 });
})();

Logging

An interface is exposed to the HttpClient constructor to allow a logging instance to be provided.

const logger: Logger = {
  info: (message: string, ...args: unknown[]) => console.log(message, ...args),
  warn: (message: string, ...args: unknown[]) => console.warn(message, ...args),
  error: (message: string, ...args: unknown[]) => console.error(message, ...args),
  debug: (message: string, ...args: unknown[]) => console.debug(message, ...args),
};
  
const httpClient = new HttpClient({
  logger,
});

Contributing

Contributing

httpclient's People

Contributors

seriouslag avatar

Stargazers

Roman avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.