forked from nest-cloud/nestcloud
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhttp.orchestrator.ts
112 lines (104 loc) · 3.88 KB
/
http.orchestrator.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import { Inject, Injectable, OnApplicationBootstrap } from '@nestjs/common';
import { AxiosRequestConfig } from 'axios';
import { ParamsMetadata } from './interfaces/params-metadata.interface';
import { getRequestParams } from './utils/params.util';
import { HTTP_OPTIONS_PROVIDER, RESPONSE, RESPONSE_BODY, RESPONSE_HEADER } from './http.constants';
import { HttpOptions } from './interfaces/http-options.interface';
import uriParams = require('uri-params');
import { Scanner, ILoadbalance, LOADBALANCE, BRAKES } from '@nestcloud/common';
import { HttpClient } from './http.client';
import { Interceptor } from './interfaces/interceptor.interface';
import { Brakes } from '@nestcloud/brakes';
interface DecoratorRequest {
instance: Function;
key: string;
method: string;
options: AxiosRequestConfig;
responseConfig: string;
paramsMetadata: ParamsMetadata;
serviceName: string;
FallbackRef: Function;
InterceptorRefs: Function[];
}
@Injectable()
export class HttpOrchestrator {
private readonly decoratorRequests = new Map<string, DecoratorRequest>();
constructor(
private readonly http: HttpClient,
private readonly scanner: Scanner,
@Inject(HTTP_OPTIONS_PROVIDER) private readonly options: HttpOptions,
) {
}
public addDecoratorRequests(
instance: Function,
method: string,
options: AxiosRequestConfig,
responseConfig: string,
paramsMetadata: ParamsMetadata,
serviceName: string,
FallbackRef: Function,
InterceptorRefs: Function[],
) {
const key = `${instance.constructor.name}__${method}`;
this.decoratorRequests.set(key, {
key,
instance,
method,
options,
responseConfig,
paramsMetadata,
serviceName,
FallbackRef,
InterceptorRefs,
});
}
async mountDecoratorRequests() {
const lb: ILoadbalance = this.scanner.findProviderByName(LOADBALANCE);
const brakes: Brakes = this.scanner.findProviderByName(BRAKES);
for (const item of this.decoratorRequests.values()) {
const {
instance,
method,
options,
responseConfig,
paramsMetadata,
serviceName,
FallbackRef,
InterceptorRefs,
} = item;
const interceptors: Interceptor[] = [];
InterceptorRefs.forEach(ref => {
const interceptor: Interceptor = this.scanner.findInjectable(ref);
if (interceptor) {
interceptors.push(interceptor);
}
});
const fallback = this.scanner.findInjectable(FallbackRef);
const http = this.http.create({ service: serviceName });
http.useLb(lb);
http.useInterceptors(...interceptors);
http.useBrakes(brakes, fallback);
instance[method] = async (...params: any[]) => {
const requestParams = getRequestParams(paramsMetadata, params);
const requestOptions = {
...this.options,
...options,
params: requestParams.params,
data: requestParams.data,
headers: requestParams.headers,
url: uriParams(options.url, requestParams.uriParams),
} as AxiosRequestConfig;
const response = await http.request(requestOptions);
switch (responseConfig) {
case RESPONSE:
return response;
case RESPONSE_HEADER:
return response.headers;
case RESPONSE_BODY:
default:
return response.data;
}
};
}
}
}