Skip to content

Byndyusoft/nest-http-client

Repository files navigation

nest-http-client

npm@latest test code style: prettier semantic-release

axios for NestJS

Comparison with @nestjs/axios

  • Promises instead of Observables
  • Allowing you use global axios with interceptors and different configs for various clients
  • endpoint requests like @octokit/endpoint

Requirements

  • Node.js v14 LTS or later
  • Yarn

Install

yarn add @byndyusoft/nest-http-client @nestjs/common axios

Usage

1. Create module
import { TRegisterAsyncOptions } from "@byndyusoft/nest-dynamic-module";
import {
  HttpClientModule,
  IHttpClientOptions,
} from "@byndyusoft/nest-http-client";
import { DynamicModule, Global, Module } from "@nestjs/common";
import urlJoin from "proper-url-join";
import qs from "qs";

import { UsersClient } from "./usersClient";

@Global()
@Module({
  providers: [UsersClient],
  exports: [UsersClient],
})
export class ClientModule {
  public static registerAsync(
    options?: TRegisterAsyncOptions<IHttpClientOptions>,
  ): DynamicModule {
    return HttpClientModule.registerClientModule(
      { module: ClientModule },
      options,
      (config) => ({
        ...config,
        baseURL: urlJoin(config?.baseURL as string, "/api/v1"),
        paramsSerializer: (params) =>
          qs.stringify(params, {
            skipNulls: true,
            arrayFormat: "repeat",
          }),
      }),
    );
  }
}
2. Module Initialization
import { Module } from "@nestjs/common";
import axios from "axios";

import { UsersClientModule } from "./clients/users";
import { ConfigModule } from "./configModule";
import { ConfigDto } from "./dtos";
import { SomeService } from "./some.service";
import { SomeController } from "./someController";

const axiosInstance = axios.create();

// You can configure axios here, e.g. interceptors

@Module({
  imports: [
    ConfigModule.forRoot(),
    UsersClientModule.registerAsync({
      inject: [ConfigDto],
      useFactory: async (config: ConfigDto) => ({
        axios: axiosInstance,
        config: config.usersApiClient,
      }),
    }),
  ],
  controllers: [SomeController],
  providers: [SomeService],
})
export class AppModule {}
3. Create client (using new endpoint method)
import { HttpClient } from "@byndyusoft/nest-http-client";
import { Injectable } from "@nestjs/common";

import {
  CreateUserDto,
  ListUsersQueryDto,
  ListUsersResponseDto,
  ParamsWithUserIdDto,
  QueryWithUserVersionDto,
  UpdateUserDto,
  UserDto,
} from "ᐸDtosᐳ";

@Injectable()
export class UsersClient {
  public constructor(private readonly httpClient: HttpClient) {}

  public createUser(request: CreateUserDto): Promise<UserDto> {
    return this.httpClient.endpoint("POST /users", request);
  }

  public deleteUser(
    request: ParamsWithUserIdDto & QueryWithUserVersionDto,
  ): Promise<UserDto> {
    return this.httpClient.endpoint(
      "DELETE /users/{userId}{?userVersion}",
      request,
    );
  }

  public getUserById(request: ParamsWithUserIdDto): Promise<UserDto> {
    return this.httpClient.endpoint("GET /users/{userId}", request);
  }

  public listUsers(
    request?: Partial<ListUsersQueryDto>,
  ): Promise<ListUsersResponseDto> {
    return this.httpClient.endpoint("GET /users", request);
  }

  public updateUser(
    request: ParamsWithUserIdDto & QueryWithUserVersionDto & UpdateUserDto,
  ): Promise<UserDto> {
    return this.httpClient.endpoint(
      "PATCH /users/{userId}{?userVersion}",
      request,
    );
  }
}
3.1. Create client (using standard methods)
import { HttpClient } from "@byndyusoft/nest-http-client";
import { Injectable } from "@nestjs/common";
import _ from "lodash";

import {
  CreateUserDto,
  ListUsersQueryDto,
  ListUsersResponseDto,
  ParamsWithUserIdDto,
  QueryWithUserVersionDto,
  UpdateUserDto,
  UserDto,
} from "ᐸDtosᐳ";

@Injectable()
export class UsersClient {
  public constructor(private readonly httpClient: HttpClient) {}

  public createUser(request: CreateUserDto): Promise<UserDto> {
    return this.httpClient.post("/users", request);
  }

  public deleteUser(
    request: ParamsWithUserIdDto & QueryWithUserVersionDto,
  ): Promise<UserDto> {
    return this.httpClient.delete(
      `/users/${encodeURIComponent(request.userId)}`,
      {
        params: _.omit(request, "userId"),
      },
    );
  }

  public getUserById(request: ParamsWithUserIdDto): Promise<UserDto> {
    return this.httpClient.get(`/users/${encodeURIComponent(request.userId)}`);
  }

  public listUsers(
    request?: Partial<ListUsersQueryDto>,
  ): Promise<ListUsersResponseDto> {
    return this.httpClient.get("/users", {
      params: request,
    });
  }

  public updateUser(
    request: ParamsWithUserIdDto & QueryWithUserVersionDto & UpdateUserDto,
  ): Promise<UserDto> {
    return this.httpClient.patch(
      `/users/${encodeURIComponent(request.userId)}`,
      _.omit(request, "userId", "userVersion"),
      {
        params: _.pick(request, "userVersion"),
      },
    );
  }
}

Maintainers

License

This repository is released under version 2.0 of the Apache License.