Skip to content

Commit

Permalink
fix: support midway global middleware use id
Browse files Browse the repository at this point in the history
  • Loading branch information
czy88840616 committed Sep 14, 2020
1 parent ce0e06a commit 8dc9ae3
Show file tree
Hide file tree
Showing 14 changed files with 234 additions and 16 deletions.
15 changes: 11 additions & 4 deletions packages/web-koa/src/framework.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ export abstract class MidwayKoaBaseFramework<T, U extends IMidwayApplication & I
};
}

public async generateMiddleware(middlewareId: string) {
const mwIns = await this.getApplicationContext().getAsync<WebMiddleware>(middlewareId);
return mwIns.resolve();
}

public async loadMidwayController(): Promise<void> {
const controllerModules = listModule(CONTROLLER_KEY);

Expand Down Expand Up @@ -325,10 +330,12 @@ export class MidwayKoaFramework extends MidwayKoaBaseFramework<IMidwayKoaConfigu
return MidwayProcessTypeEnum.APPLICATION;
},

generateController: (controllerMapping: string,
routeArgsInfo?: RouterParamValue[],
routerResponseData?: any []) => {
return this.generateController(controllerMapping, routeArgsInfo, routerResponseData);
generateController: (controllerMapping: string) => {
return this.generateController(controllerMapping);
},

generateMiddleware: async (middlewareId: string) => {
return this.generateMiddleware(middlewareId);
}
});
}
Expand Down
3 changes: 2 additions & 1 deletion packages/web-koa/src/interface.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { IMidwayApplication, IMidwayContext } from '@midwayjs/core';
import * as koa from 'koa';
import { Context, DefaultState, Middleware } from 'koa';
import { RouterParamValue } from "@midwayjs/decorator";
import { RouterParamValue } from '@midwayjs/decorator';

export type IMidwayKoaContext = IMidwayContext & Context;
export type IMidwayKoaApplication = IMidwayApplication & koa<DefaultState, IMidwayKoaContext> & {
Expand All @@ -10,6 +10,7 @@ export type IMidwayKoaApplication = IMidwayApplication & koa<DefaultState, IMidw
routeArgsInfo?: RouterParamValue[],
routerResponseData?: any []
): Middleware<DefaultState, IMidwayKoaContext>;
generateMiddleware(middlewareId: string): Promise<Middleware<DefaultState, IMidwayKoaContext>>;
};

export interface IMidwayKoaApplicationPlus {
Expand Down
23 changes: 21 additions & 2 deletions packages/web/src/app.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
import { Bootstrap } from "@midwayjs/bootstrap";
import { Framework } from "./index";
import { Bootstrap } from '@midwayjs/bootstrap';
import { Framework } from './index';

class AppBootHook {
app;
bootstrap;
framework;
appMiddleware = [];

constructor(app) {
this.app = app;
}

configDidLoad() {
// 先清空,防止加载到 midway 中间件出错
this.appMiddleware = this.app.config.appMiddleware;
this.app.config.appMiddleware = [];
}

async didLoad() {
// 这里的逻辑是为了兼容老 cluster 模式
if (this.app.options['isClusterMode'] !== false) {
Expand All @@ -25,6 +32,18 @@ class AppBootHook {
await Bootstrap.run();
this.app.options['webFramework'] = this.framework;
}

// 等 midway 加载完成后,再去 use 中间件
for (const name of this.appMiddleware) {
if (this.app.getApplicationContext().registry.hasDefinition(name)) {
const mwIns = await this.app.generateMiddleware(name);
this.app.use(mwIns);
} else {
// egg
this.app.use(this.app.middlewares[name](this.app.config[name]));
}
}

}

async willReady() {
Expand Down
99 changes: 95 additions & 4 deletions packages/web/src/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import type { MidwayWebFramework } from './framework';
import { RouterParamValue } from '@midwayjs/decorator';
import { parseNormalDir } from './utils';
import * as extend from 'extend2';

// import { join } from 'path';
import { EggAppInfo } from 'egg';
import { IMidwayWebApplication } from './interface';

const {
AppWorkerLoader,
Expand All @@ -12,12 +13,24 @@ const {
Agent,
} = require('egg');

// const pathMatching = require('egg-path-matching');

const EGG_LOADER = Symbol.for('egg#loader');
const EGG_PATH = Symbol.for('egg#eggPath');

export const createAppWorkerLoader = AppWorkerLoader => {
class EggAppWorkerLoader extends (AppWorkerLoader as any) {

app: IMidwayWebApplication & {
appOptions: {
typescript?: boolean;
isTsMode?: boolean;
},
appDir: string;
baseDir: string;
middlewares: [];
};

getEggPaths() {
if (!this.appDir) {
// 这里的逻辑是为了兼容老 cluster 模式
Expand All @@ -36,9 +49,64 @@ export const createAppWorkerLoader = AppWorkerLoader => {
return super.getEggPaths();
}

loadMiddleware(opt) {
return super.loadMiddleware(opt);
}
// loadMiddleware(opt) {
// this.timing.start('Load Middleware');
// const app = this.app;
//
// console.log(app.middlewares)
//
// // load middleware to app.middleware
// opt = Object.assign({
// call: false,
// override: true,
// caseStyle: 'lower',
// directory: this.getLoadUnits().map(unit => join(unit.path, 'app/middleware')),
// }, opt);
// const middlewarePaths = opt.directory;
// this.loadToApp(middlewarePaths, 'middlewares', opt);
//
// for (const name in app.middlewares) {
// Object.defineProperty(app.middleware, name, {
// get() {
// return app.middlewares[name];
// },
// enumerable: false,
// configurable: false,
// });
// }
//
// this.options.logger.info('Use coreMiddleware order: %j', this.config.coreMiddleware);
// this.options.logger.info('Use appMiddleware order: %j', this.config.appMiddleware);
//
// // use middleware ordered by app.config.coreMiddleware and app.config.appMiddleware
// const middlewareNames = this.config.coreMiddleware.concat(this.config.appMiddleware);
// const middlewaresMap = new Map();
// for (const name of middlewareNames) {
// if (!app.middlewares[name]) {
// throw new TypeError(`Middleware ${name} not found`);
// }
// if (middlewaresMap.has(name)) {
// throw new TypeError(`Middleware ${name} redefined`);
// }
// middlewaresMap.set(name, true);
//
// const options = this.config[name] || {};
// let mw: any = app.middlewares[name];
// mw = mw(options, app);
// mw._name = name;
// // middlewares support options.enable, options.ignore and options.match
// mw = wrapMiddleware(mw, options);
// if (mw) {
// app.use(mw);
// this.options.logger.info('[egg:loader] Use middleware: %s', name);
// } else {
// this.options.logger.info('[egg:loader] Disable middleware: %s', name);
// }
// }
//
// this.options.logger.info('[egg:loader] Loaded middleware from %j', middlewarePaths);
// this.timing.end('Load Middleware');
// }

protected getAppInfo(): EggAppInfo {
if (!this.appInfo) {
Expand Down Expand Up @@ -129,6 +197,10 @@ export const createEggApplication = Application => {
return this.midwayWebFramework.generateController(controllerMapping, routeArgsInfo, routerResponseData);
}

async generateMiddleware(middlewareId: string) {
return this.midwayWebFramework.generateMiddleware(middlewareId);
}

get baseDir() {
return this.loader.baseDir;
}
Expand Down Expand Up @@ -208,3 +280,22 @@ export class EggAgent extends BaseEggAgent {

export { EggApplication as Application };
export { EggAgent as Agent };

// function wrapMiddleware(mw, options) {
// // support options.enable
// if (options.enable === false) return null;
//
// // support generator function
// // mw = utils.middleware(mw);
//
// // support options.match and options.ignore
// if (!options.match && !options.ignore) return mw;
// const match = pathMatching(options);
//
// const fn = (ctx, next) => {
// if (!match(ctx)) return next();
// return mw(ctx, next);
// };
// fn._name = mw._name + 'middlewareWrapper';
// return fn;
// }
1 change: 0 additions & 1 deletion packages/web/src/framework.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,6 @@ export class MidwayWebFramework extends MidwayKoaBaseFramework<IMidwayWebConfigu

// TODO 单进程模式下区分进程类型??
return MidwayProcessTypeEnum.APPLICATION;

}
});
}
Expand Down
6 changes: 3 additions & 3 deletions packages/web/src/interface.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Context, Application } from 'egg';
import { IMidwayApplication, IMidwayContext } from '@midwayjs/core';
import { IMidwayKoaConfigurationOptions } from '@midwayjs/koa';
import { IMidwayKoaConfigurationOptions, IMidwayKoaContext } from '@midwayjs/koa';
import { DefaultState, Middleware } from 'koa';
import { RouterParamValue } from "@midwayjs/decorator";

export type IMidwayWebApplication = IMidwayApplication & Application & {
generateController?(controllerMapping: string, routeArgsInfo?: RouterParamValue[], routerResponseData?: any []);
generateController(controllerMapping: string);
generateMiddleware(middlewareId: string): Promise<Middleware<DefaultState, IMidwayKoaContext>>;
};
export type IMidwayWebContext = IMidwayContext & Context;

Expand Down
9 changes: 8 additions & 1 deletion packages/web/test/feature.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { IMidwayWebApplication } from "../src";

describe('/test/feature.test.ts', () => {

describe('test new features', () => {
describe('test new decorator', () => {
let app: IMidwayWebApplication;
beforeAll(async () => {
app = await creatApp('feature/base-app');
Expand All @@ -25,4 +25,11 @@ describe('/test/feature.test.ts', () => {
});
});

it('should test global use midway middleware id in egg', async () => {
const app = await creatApp('feature/base-app-middleware');
const result = await createHttpRequest(app).get('/')
expect(result.text).toEqual('1111222233334444');
await closeApp(app);
});

});
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "ali-demo-global-middleware"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const keys = 'key';

export const hello = {
a: 1,
b: 2,
d: [1, 2, 3],
};

export const middleware = ['globalMiddleware2'];
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

exports.hello = {
b: 4,
c: 3,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default {
'static': false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { App, Configuration } from '@midwayjs/decorator';
import { IMidwayWebApplication } from '../../../../../src';

@Configuration({
importConfigs: [
'./config'
]
})
export class ContainerConfiguration {

@App()
app: IMidwayWebApplication;

async onReady() {
this.app.use(await this.app.generateMiddleware('globalMiddleware1'));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Controller, Get, Inject, Provide, } from '@midwayjs/decorator';
import { IMidwayWebContext } from '../../../../../../src';

@Provide()
@Controller('/', { middleware: ['globalMiddleware3'] })
export class APIController {
@Inject()
ctx: IMidwayWebContext;

@Get('/', { middleware: ['globalMiddleware4'] })
async home() {
return this.ctx.state['a'] + this.ctx.state['b'] + this.ctx.state['c'] + this.ctx.state['d'];
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Provide } from '@midwayjs/decorator';
import { IMidwayWebContext } from '../../../../../../src';

@Provide()
export class GlobalMiddleware1 {
resolve() {
return async (ctx: IMidwayWebContext, next) => {
ctx.state.a = '1111';
await next();
}
}
}

@Provide()
export class GlobalMiddleware2 {
resolve() {
return async (ctx: IMidwayWebContext, next) => {
ctx.state.b = '2222';
await next();
}
}
}

@Provide()
export class GlobalMiddleware3 {
resolve() {
return async (ctx: IMidwayWebContext, next) => {
ctx.state.c = '3333';
await next();
}
}
}

@Provide()
export class GlobalMiddleware4 {
resolve() {
return async (ctx: IMidwayWebContext, next) => {
ctx.state.d = '4444';
await next();
}
}
}

0 comments on commit 8dc9ae3

Please sign in to comment.