Skip to content

Commit d5a6604

Browse files
jbl428imdudu1
andcommitted
feat: implement http method to injector
Co-authored-by: imdudu1 <[email protected]>
1 parent 3d776aa commit d5a6604

File tree

2 files changed

+93
-30
lines changed

2 files changed

+93
-30
lines changed

lib/node-fetch.injector.spec.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
import { MetadataScanner } from "@nestjs/core";
22
import { beforeEach, describe, test, expect } from "vitest";
33
import {
4+
DeleteExchange,
45
GetExchange,
6+
HeadExchange,
57
HttpInterface,
8+
OptionsExchange,
9+
PatchExchange,
610
PathVariable,
11+
PostExchange,
12+
PutExchange,
713
RequestParam,
814
} from "./decorators";
915
import { StubDiscoveryService } from "./fixture/stub-discovery.service";
@@ -25,6 +31,25 @@ describe("NodeFetchInjector", () => {
2531
discoveryService.clear();
2632
});
2733

34+
test("should not wrap method if there is no http interface decorator", async () => {
35+
// given
36+
class SampleClient {
37+
@GetExchange("/api")
38+
async request(): Promise<string> {
39+
return "request";
40+
}
41+
}
42+
const instance = discoveryService.addProvider(SampleClient);
43+
nodeFetchInjector.onModuleInit();
44+
45+
// when
46+
const actual = await instance.request();
47+
48+
// then
49+
expect(actual).toBe("request");
50+
expect(httpClient.requestInfo).toHaveLength(0);
51+
});
52+
2853
test("should not wrap method if there is no http exchange", async () => {
2954
// given
3055
@HttpInterface()
@@ -161,4 +186,33 @@ describe("NodeFetchInjector", () => {
161186
"https://example.com/api?keyword=search&page=1&isActive=true"
162187
);
163188
});
189+
190+
test.each([
191+
["GET", GetExchange],
192+
["POST", PostExchange],
193+
["PUT", PutExchange],
194+
["DELETE", DeleteExchange],
195+
["PATCH", PatchExchange],
196+
["HEAD", HeadExchange],
197+
["OPTIONS", OptionsExchange],
198+
])("should make the request using %s method", async (method, decorator) => {
199+
// given
200+
@HttpInterface()
201+
class SampleClient {
202+
@decorator("https://example.com/api")
203+
async request(): Promise<string> {
204+
return "request";
205+
}
206+
}
207+
const instance = discoveryService.addProvider(SampleClient);
208+
httpClient.addResponse({ status: "ok" });
209+
nodeFetchInjector.onModuleInit();
210+
211+
// when
212+
await instance.request();
213+
214+
// then
215+
expect(httpClient.requestInfo).toHaveLength(1);
216+
expect(httpClient.requestInfo[0].method).toBe(method);
217+
});
164218
});

lib/node-fetch.injector.ts

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -26,45 +26,54 @@ export class NodeFetchInjector implements OnModuleInit {
2626

2727
httpProviders.forEach((wrapper) => {
2828
const prototype = wrapper.metatype.prototype;
29-
const baseUrl: string = Reflect.getMetadata(
29+
const baseUrl: string | undefined = Reflect.getMetadata(
3030
HTTP_INTERFACE_METADATA,
3131
prototype
3232
);
33-
const methodNames = this.metadataScanner.getAllMethodNames(prototype);
3433

35-
methodNames.forEach((methodName) => {
36-
const getMetadata = this.makeMetadataGetter(prototype, methodName);
37-
const httpExchangeMetadata = getMetadata<HttpExchangeMetadata>(
38-
HTTP_EXCHANGE_METADATA
39-
);
34+
if (typeof baseUrl === "undefined") {
35+
return;
36+
}
4037

41-
if (typeof httpExchangeMetadata === "undefined") {
42-
return;
43-
}
38+
this.metadataScanner
39+
.getAllMethodNames(prototype)
40+
.forEach((methodName) => {
41+
const getMetadata = this.makeMetadataGetter(prototype, methodName);
42+
const httpExchangeMetadata = getMetadata<HttpExchangeMetadata>(
43+
HTTP_EXCHANGE_METADATA
44+
);
4445

45-
const pathMetadata = getMetadata<PathVariableMetadata>(
46-
PATH_VARIABLE_METADATA
47-
);
48-
const requestParamMetadata = getMetadata<RequestParamMetadata>(
49-
REQUEST_PARAM_METADATA
50-
);
46+
if (typeof httpExchangeMetadata === "undefined") {
47+
return;
48+
}
5149

52-
wrapper.instance[methodName] = async (...args: any[]) => {
53-
const urlBuilder = new URLBuilder(
54-
baseUrl,
55-
httpExchangeMetadata.url,
56-
args,
57-
{
58-
pathParam: pathMetadata,
59-
queryParam: requestParamMetadata,
60-
}
50+
const pathMetadata = getMetadata<PathVariableMetadata>(
51+
PATH_VARIABLE_METADATA
52+
);
53+
const requestParamMetadata = getMetadata<RequestParamMetadata>(
54+
REQUEST_PARAM_METADATA
6155
);
6256

63-
return await this.httpClient
64-
.request(new Request(urlBuilder.build()))
65-
.then(async (response) => await response.json());
66-
};
67-
});
57+
wrapper.instance[methodName] = async (...args: any[]) => {
58+
const urlBuilder = new URLBuilder(
59+
baseUrl,
60+
httpExchangeMetadata.url,
61+
args,
62+
{
63+
pathParam: pathMetadata,
64+
queryParam: requestParamMetadata,
65+
}
66+
);
67+
68+
return await this.httpClient
69+
.request(
70+
new Request(urlBuilder.build(), {
71+
method: httpExchangeMetadata.method,
72+
})
73+
)
74+
.then(async (response) => await response.json());
75+
};
76+
});
6877
});
6978
}
7079

0 commit comments

Comments
 (0)