npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

resilient-http-client

v2.0.1

Published

This is an augmented [Angular HttpClient][angular-http-client] which overrides the get method to enrich resilience behaviour.

Downloads

375

Readme

Resilience Client

This is an augmented Angular HttpClient which overrides the get method to enrich resilience behaviour.

Preconditions

Install it via yarn add resilient-http-client

Docs

Default configuration

The default config is the following:

export const DEFAULT_RESILIENCE_CONFIG: Partial<IResilienceConfig> = {
    /* the ms after which a request is reported via call
        to onRequestDelayed fn that it is delayed*/
    isDelayedAfterMs: 3000,
    /* flag to enable/disable the whole resilience behaviour */
    disableRetry: false,
    /* flag to enable/disable automatic log output for the response payload */
    logResult: false,
    /* flag to enable/disable automatic trace of request execution time */
    trace: false,
    /* flag to enable/disable 'wait on error' behaviour.
        If enabled, onWaitingForUserDecision fn will be called in case the retry loop failed.
        The user can restart the loop or cancel the request be sending a boolean flag to the
        userRetryOrCancel subject */
    waitForUserDecision: false,
    /* Default list of status codes for which a retry will be done.
        All other error status codes will cause an exception and cause the stream to close.
        No resilience behaviour will be added, except eventing (onFail, onRequestStart, onRequestFinalze)
        and, if configured via topicToConfigDict, a fallback response will be returned. */
    retryOnStatusCodeList: [
        HttpStatusCode.RequestTimeout,
        HttpStatusCode.Locked,
        HttpStatusCode.TooManyRequests,
        HttpStatusCode.InternalServerError,
        HttpStatusCode.BadGateway,
        HttpStatusCode.ServiceUnavailable,
        HttpStatusCode.GatewayTimeout,
    ],
    /* Default retry interval list in milliseconds. This list means: if the initial request fails and
        it was a status code from the retryOnStatusCodeList list, retry immediately, then after waiting for
        200 if it still failed, and then after additional 500 again, etc. until there is no more ms in the array.
        The retry loop will stop after looping through the retryIntervalInMillisList array.
        If waitForUserDecision was false, it will then throw an expection and close the stream.
        In this case, if configured via topicToConfigDict, a fallback response will be returned or it will just throw.
    */
    retryIntervalInMillisList: [0, 200, 500, 1000, 1000],
    /* The possibility to:
        - override boolean flags (waitForUserDecision, disableRetry, logResult, trace) and
        - specify a custom failMessage (recommendation is to use a localization key here)
          and specify a topic specific failover response value. Hint: this can also be used for Regarding Topics: mocking 
          responses of not yet implemented backend endpoints in dev state.
          Regarding Topics: Recommendation is to use a string enum for all topics in your app.
          You can use them also to switch case custom visualization when handling the events centrally for example
          in an SnackbarService which consumes all events from the resillience service.
   */
    topicToConfigDict: {},
    /* Event listener callback for onWaitingForUserDecision event. Will be called if retry loop failed
        and waitForUserDecision flag was true globally or for the regarding topic, configured
        via topicToConfigDict. */ 
    onWaitingForUserDecision: (
        // the topic of the request, typically the name of the API fn or its intent
        topic: string,
        /* unique id for the current request. Will be the same for each event callback invocation
           for the regarding request. */
        uuid: string, 
        retryCount: number, // how many times did the resilience pattern tried to retry the failed request
        failedOnStatusCode: HttpStatusCode, // the HttpStatusCode of the last failed request 
        userRetryOrCancel: Subject<boolean>, // subject to cause retry loop to start again (true) or cancel the request (false)
    ): void => {},
    onFail: (topic: string, uuid: string, message: string): void => {},
    onRequestDelayed: (topic: string, uuid: string): void => {},
    onRequestRetry: (
        topic: string,
        uuid: string,
        retryCount: number,
        nextRetry: number, // next retry will be done in x ms
        failedOnHttpStatusCode: HttpStatusCode,
    ): void => {},
    onRequestStart: (topic: string, uuid: string): void => {},
    onRequestFinalize: (topic: string, uuid: string): void => {},
};

Recommended: use a builder for topic specific resilience config enrichment

// RESILIENT_API_TOPIC = string enum with all resilience topics of your app
export const buildResilienceConfigForTopic = (topic: RESILIENT_API_TOPIC): IResilienceConfig => {
    return {
        ...DEFAULT_RESILIENCE_CONFIG, // the default resilience config from this library
        ...RESILIENCE_CONFIG, // a reference to your global resilience config, typically located in ./src/app/config/resilience.config.ts
        topic, // add the topic flag
    } as IResilienceConfig;
};

Demo usage:

@Injectable({
providedIn: 'root',
})
export class SampleApiService {

    constructor(
        private readonly resilientHttpClientService: ResilientHttpClientService,
    ) {
    }

    public getYourDtoList$(bySomeId: ISampleId): Observable<ISampleDto[]> {
        /* everything as like the normal use of Angular HttpClient, just enriched by a topic unspecific (global) or
           topic specific resilient config which specifies the wanted failover behaviour */
        return this.resilientHttpClientService
            .get<
                ISampleDto[]
            >('/some/url/to/the/dto/api', buildResilienceConfigForTopic(RESILIENT_API_TOPIC.SAMPLE_DTO_LIST));
    }
}

The code documentation

Take a look at the code documentation by opening the index.html file.

  • Folder: /doc/code

Test coverage report

Take a look at the test coverage by opening the index.html file.

  • Folder: /doc/test

Love the Resilience Client? Give our repo a star :star: :arrow_up:.