0.0.2 • Published 8 months ago

@redhare/http v0.0.2

Weekly downloads
-
License
-
Repository
-
Last release
8 months ago

@infra-node-kit/http

Background

Currently Http module code is hardcoded into the template code which will make future update or bug fix infeasible. The Http module code should be extracted into an independent nestjs module. In this way developer can not only update the corresponding package when new features are released, but also have an option to choose whether they want to use our module in their project.

Features

  • Implement a Http module with nestjs standard modules(https://docs.nestjs.com/modules) technique which provides a variety of high-frequency use http request methods.
  • request multiplexing.
  • current limiting. base on p-queue
  • (WIP)Need to consider using circuit breaker pattern.

How to use

Install

yarn install @infra-node-kit/http

Basic Usage

normal

It's same with @nestjs/axios. The usage of @nestjs/axios can be found at https://docs.nestjs.com/techniques/http-module.

Axios can be configured with a variety of options to customize the behavior of the HttpService. Besides the AxiosRequestConfig, you can also configure with the following options:

OptionDescriptionTypeDefault
retryMaxCountmax retry count when can't get response.Number1
retryDelayretry delayNumber500 (ms)
concurrencyconcurrency limit.NumberInfinity
skipPathsthe paths which the log is not requiredstring[][]
skipBodyPathsWhether to hide the body field in the logbooleanfalse
skipHeadersPathsWhether to hide the headers field in the logbooleanfalse

The path rule can reference to path-to-regexp

Besides path-to-regexp rules you can use * to match all the paths.

HttpModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    timeout: configService.get('HTTP_TIMEOUT'),
    maxRedirects: configService.get('HTTP_MAX_REDIRECTS'),
    retryMaxCount: 3,
    retryDelay: 1000
  }),
  inject: [ConfigService],
});

Best Practice

If you want to use a lot of servers, you can create a module for each server which can customize the behavior of the HttpService.

demo:

// server 1
@Module({
  controllers: [],
  imports: [
    HttpModule.register({
      baseURL: 'https://api.rap.shopee.io/app/mock/110',
      concurrency: 1,
    }),
  ],
  providers: [Server1Service],
  exports: [Server1Service],
})
export class Server1Module {}

// server 2, have different configurations
@Module({
  controllers: [],
  imports: [
    HttpModule.register({
      baseURL: 'https://api.rap.shopee.io/app/mock/120',
      timeout: 5000,
      concurrency: 1,
    }),
  ],
  providers: [Server2Service],
  exports: [Server2Service],
})
export class Server2Module {}

// Biz modules can combine these modules
@Module({
  imports: [
    Server1Module,
    Server2Module
  ],
})
export class BizModule {}

working with rapper

Get more information about rap: link

First import HttpModule.

import { HttpModule } from '@infra-node-kit/http'
import { Module } from '@nestjs/common'
import { AppController } from './app.controller'
import { AppService } from './app.service'

@Module({
  imports: [HttpModule.register({ concurrency: 1000 })],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Next, get the method request from the instance of HttpService. After that, hava fun with rapper.

import { NestFactory } from '@nestjs/core'
import { HttpService } from '@infra-node-kit/http'
import { AppModule } from './app.module'
import { overrideFetch } from './rapper'

async function bootstrap() {
  const app = await NestFactory.create(AppModule)
  const httpService = app.get(HttpService)
  overrideFetch(async ({ url, method, params }) => {
    try {
      const response = await httpService.request({
        baseURL: 'https://api.rap.shopee.io/app/mock/110',
        method,
        url,
        data: params,
      })
      return response.data
    } catch (error) {
      return Promise.reject(error)
    }
  })
  await app.listen(3000)
}
bootstrap()
import { fetch } from '../../rapper'

@Controller('example')
export class ExampleController {
  @Get('getTestRap')
  async getTestRap(): Promise<string> {
    return await fetch['GET/test/get']({})
  }
}

API

request method

provide the following methods:

return an AxiosResponse

downloadFile(configs)

configs:

  • sourceUrl <string>
  • destinationFolder <string>
  • options:
    • name <string>
    • override <boolean>, defalut is false
    • autoCreateFolder <boolean>, defalut is false

axiosRef

axiosRef is provided. You can use it to intercept requests or specify config defaults that will be applied to every request. But please use the above method to send request, it will loss of concurrency if you send request by axiosRef directly.

0.0.2

8 months ago

0.0.1

8 months ago