|
@@ -0,0 +1,78 @@
|
|
|
+import { Config, Inject, InjectClient, Provide } from '@midwayjs/core';
|
|
|
+import { Context } from '@midwayjs/koa';
|
|
|
+import { RequestBase } from '../interface/proxy.interface';
|
|
|
+import { get, lowerCase, pick } from 'lodash';
|
|
|
+import { HttpServiceFactory, HttpService } from '@midwayjs/axios';
|
|
|
+import { Axios } from '@midwayjs/axios';
|
|
|
+@Provide()
|
|
|
+export class ProxyService {
|
|
|
+ @Inject()
|
|
|
+ ctx: Context;
|
|
|
+
|
|
|
+ @Config('axios.clients')
|
|
|
+ axiosClients: object;
|
|
|
+
|
|
|
+ @InjectClient(HttpServiceFactory, 'default')
|
|
|
+ serviceAxios: HttpService;
|
|
|
+
|
|
|
+ @Inject()
|
|
|
+ sf: HttpServiceFactory;
|
|
|
+
|
|
|
+ getRequstBase(): RequestBase {
|
|
|
+ const request = this.ctx.request;
|
|
|
+ const result: RequestBase = pick(request, [
|
|
|
+ 'method',
|
|
|
+ 'header',
|
|
|
+ 'path',
|
|
|
+ 'query',
|
|
|
+ 'querystring',
|
|
|
+ 'body',
|
|
|
+ 'rawBody',
|
|
|
+ 'host',
|
|
|
+ 'ip',
|
|
|
+ 'originalUrl',
|
|
|
+ ]) as RequestBase;
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ async toProxy() {
|
|
|
+ const rb: RequestBase = this.getRequstBase();
|
|
|
+ // 解析路由前缀
|
|
|
+ const uri = rb.originalUrl;
|
|
|
+ const keys = Object.keys(this.axiosClients);
|
|
|
+ let url;
|
|
|
+ for (const prefix of keys) {
|
|
|
+ const regRules = `^(${prefix})`;
|
|
|
+ const reg = new RegExp(regRules);
|
|
|
+ const res = reg.test(uri);
|
|
|
+ if (!res) continue;
|
|
|
+ const clientConfig = this.axiosClients[prefix];
|
|
|
+ const baseURL = clientConfig.baseURL;
|
|
|
+ // 去掉前缀
|
|
|
+ // url = uri.replace(reg, baseURL);
|
|
|
+ // 保留前缀(目前采用这一方式处理)
|
|
|
+ url = `${baseURL}${rb.originalUrl}`;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (!url) return;
|
|
|
+ const reqConfig: any = {
|
|
|
+ url,
|
|
|
+ method: rb.method,
|
|
|
+ headers: rb.header,
|
|
|
+ };
|
|
|
+ if (lowerCase(rb.method) === 'post') reqConfig.data = rb.body;
|
|
|
+ const res = await this.serviceAxios.request(reqConfig);
|
|
|
+ if (res.status !== 200) throw new Error('proxy service request error');
|
|
|
+ return res.data;
|
|
|
+ }
|
|
|
+
|
|
|
+ async getAxios(clientConfig: object): Promise<Axios.AxiosInstance> {
|
|
|
+ const rb: RequestBase = this.getRequstBase();
|
|
|
+ const axi = await this.sf.createInstance({
|
|
|
+ ...clientConfig,
|
|
|
+ header: get(rb, 'header'),
|
|
|
+ });
|
|
|
+ return axi;
|
|
|
+ }
|
|
|
+}
|