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; console.log(url); 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 { const rb: RequestBase = this.getRequstBase(); const axi = await this.sf.createInstance({ ...clientConfig, header: get(rb, 'header'), }); return axi; } }