Skip to content

Commit

Permalink
feat: add endpoint requests
Browse files Browse the repository at this point in the history
  • Loading branch information
KillWolfVlad committed Aug 9, 2022
1 parent 579ba6f commit 0a73b3a
Show file tree
Hide file tree
Showing 8 changed files with 309 additions and 10 deletions.
73 changes: 65 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ axios for NestJS
- [Promises instead of Observables](https://github.com/nestjs/axios/issues/271)
- `axios` dependency [is not pinning](https://github.com/nestjs/axios/pull/149#issuecomment-925764515), you must provide it by yourself (e.g. get it from `HttpService`)
- Allowing you use global `axios` with interceptors and different configs for various clients
- `endpoint` requests like `@octokit/endpoint`

## Requirements

Expand Down Expand Up @@ -39,12 +40,12 @@ import { DynamicModule, Global, Module } from "@nestjs/common";
import urlJoin from "proper-url-join";
import qs from "qs";

import * as providers from "./providers";
import { UsersClient } from "./usersClient";

@Global()
@Module({
providers: Object.values(providers),
exports: Object.values(providers),
providers: [UsersClient],
exports: [UsersClient],
})
export class ClientModule {
public static registerAsync(
Expand All @@ -70,13 +71,69 @@ export class ClientModule {
</details>

<details>
<summary>2. Create client</summary>
<summary>2. Create client (using new endpoint method)</summary>

```typescript
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,
);
}
}
```

</details>

<details>
<summary>2.1. Create client (using standard methods)</summary>

```typescript
import { HttpClient } from "@byndyusoft/nest-http-client";
import { Injectable } from "@nestjs/common";
import _ from "lodash";
import { keys } from "ts-transformer-keys";

import {
CreateUserDto,
Expand All @@ -102,7 +159,7 @@ export class UsersClient {
return this.httpClient.delete(
`/users/${encodeURIComponent(request.userId)}`,
{
params: _.pick(request, keys<QueryWithUserVersionDto>()),
params: _.omit(request, "userId"),
},
);
}
Expand All @@ -124,9 +181,9 @@ export class UsersClient {
): Promise<UserDto> {
return this.httpClient.patch(
`/users/${encodeURIComponent(request.userId)}`,
_.pick(request, keys<UpdateUserDto>()),
_.omit(request, "userId", "userVersion"),
{
params: _.pick(request, keys<QueryWithUserVersionDto>()),
params: _.pick(request, "userVersion"),
},
);
}
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
"!**/*spec.ts"
],
"scripts": {
"_test:cov": "jest --coverage",
"prebuild": "shx rm -rf ./dist",
"build": "yarn run prebuild && yarn run build:src",
"build:src": "tsc --project ./tsconfig.build.json",
Expand All @@ -37,7 +36,8 @@
"lint:prettier:fix": "prettier --ignore-path ./.gitignore --write \"./**/*.{ts,js,json,yaml,yml,md}\"",
"prepublishOnly": "pinst --disable",
"postpublish": "pinst --enable",
"test": "jest"
"test": "jest",
"test:cov": "jest --coverage"
},
"jest": {
"collectCoverageFrom": [
Expand Down Expand Up @@ -72,6 +72,7 @@
"dependencies": {
"@byndyusoft/nest-dynamic-module": "^1.0.0",
"deepmerge": "^4.2.2",
"lodash": "^4.17.21",
"tslib": "^2.4.0"
},
"devDependencies": {
Expand All @@ -81,6 +82,7 @@
"@commitlint/config-conventional": "17.0.3",
"@nestjs/common": "8.4.7",
"@types/jest": "28.1.6",
"@types/lodash": "4.14.182",
"@types/node": "14.18.22",
"axios": "0.27.2",
"eslint": "8.20.0",
Expand Down
117 changes: 117 additions & 0 deletions src/__tests__/parseEndpoint.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
* Copyright 2022 Byndyusoft
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { parseEndpoint } from "../parseEndpoint";

describe("parseEndpoint", () => {
describe("UsersClient", () => {
it("createUser", () => {
expect(
parseEndpoint("POST /users", {
name: "user1",
email: "user1@example.com",
}),
).toMatchInlineSnapshot(`
Object {
"data": Object {
"email": "user1@example.com",
"name": "user1",
},
"method": "POST",
"params": Object {},
"url": "/users",
}
`);
});

it("deleteUser", () => {
expect(
parseEndpoint("DELETE /users/{userId}{?userVersion}", {
userId: "1",
userVersion: 5,
}),
).toMatchInlineSnapshot(`
Object {
"method": "DELETE",
"params": Object {
"userVersion": 5,
},
"url": "/users/1",
}
`);
});

it("getUserById", () => {
expect(
parseEndpoint("GET /users/{userId}", {
userId: "1",
}),
).toMatchInlineSnapshot(`
Object {
"method": "GET",
"params": Object {},
"url": "/users/1",
}
`);
});

it("listUsers", () => {
expect(
parseEndpoint("GET /users", {
userIds: ["1", "2"],
pageSize: 10,
pageToken: "0",
}),
).toMatchInlineSnapshot(`
Object {
"method": "GET",
"params": Object {
"pageSize": 10,
"pageToken": "0",
"userIds": Array [
"1",
"2",
],
},
"url": "/users",
}
`);
});

it("updateUser", () => {
expect(
parseEndpoint("PATCH /users/{userId}{?userVersion}", {
userId: "1",
userVersion: 5,
name: "user1",
email: "user1@example.com",
}),
).toMatchInlineSnapshot(`
Object {
"data": Object {
"email": "user1@example.com",
"name": "user1",
},
"method": "PATCH",
"params": Object {
"userVersion": 5,
},
"url": "/users/1",
}
`);
});
});
});
6 changes: 6 additions & 0 deletions src/httpClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ export class HttpClient {
return response.data;
}

public async endpoint<T = any>(route: string, request?: any): Promise<T> {
const response = await this.httpCoreClient.endpoint<T>(route, request);

return response.data;
}

public async get<T = any>(
url: string,
config?: AxiosRequestConfig,
Expand Down
8 changes: 8 additions & 0 deletions src/httpCoreClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import deepMerge from "deepmerge";

import { IHttpClientOptions } from "./httpClientOptionsInterface";
import { HttpClientOptionsToken } from "./httpClientOptionsToken";
import { parseEndpoint, TEndpointRequest } from "./parseEndpoint";

@Injectable()
export class HttpCoreClient {
Expand All @@ -43,6 +44,13 @@ export class HttpCoreClient {
return this.axios.delete(url, this.mergeConfigs(config));
}

public endpoint<T = any>(
route: string,
request?: any,
): Promise<AxiosResponse<T>> {
return this.request(parseEndpoint(route, request as TEndpointRequest));
}

public get<T = any>(
url: string,
config?: AxiosRequestConfig,
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ export * from "./httpClientModule";
export * from "./httpClientOptionsInterface";
export * from "./httpClientOptionsToken";
export * from "./httpCoreClient";
export * from "./parseEndpoint";

0 comments on commit 0a73b3a

Please sign in to comment.