Skip to content
This repository has been archived by the owner on Jul 2, 2020. It is now read-only.

Commit

Permalink
feat: support koa application (#162)
Browse files Browse the repository at this point in the history
  • Loading branch information
czy88840616 committed May 14, 2020
1 parent b949b59 commit 364d62b
Show file tree
Hide file tree
Showing 19 changed files with 460 additions and 256 deletions.
2 changes: 2 additions & 0 deletions packages/faas/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from '@midwayjs/faas-typings';
export * from './dist/index';
2 changes: 1 addition & 1 deletion packages/faas/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@midwayjs/faas",
"version": "0.2.92",
"main": "dist/index",
"typings": "dist/index.d.ts",
"typings": "index.d.ts",
"dependencies": {
"@midwayjs/core": "^2.0.0",
"@midwayjs/decorator": "^2.0.8",
Expand Down
4 changes: 2 additions & 2 deletions packages/faas/src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ export class FaaSContainerConfiguration implements ILifeCycle {

async onReady() {
// add middleware from user config
for (const mw of this.middleware) {
this.app.addGlobalMiddleware(mw);
if (this.app?.use) {
await this.app.useMiddleware(this.middleware);
}
}
}
1 change: 0 additions & 1 deletion packages/faas/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export * from '@midwayjs/faas-typings';
export * from './interface';
export * from './starter';
export * from '@midwayjs/core';
Expand Down
15 changes: 8 additions & 7 deletions packages/faas/src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@ import { MidwayRequestContainer, IMidwayCoreApplication } from '@midwayjs/core';
import { FaaSHTTPContext } from '@midwayjs/faas-typings';

export interface IFaaSApplication extends IMidwayCoreApplication {
start(opts?);
handleInvokeWrapper(handlerMapping: string);
getInitializeContext();
addGlobalMiddleware(mw: string);
use(
middleware: (() => (context: any, next: () => Promise<any>) => any) | string
);
useMiddleware(mw: string[]);
}

/**
* @deprecated same as IFaaSApplication
*/
export type IFaaSStarter = IFaaSApplication;
export interface IFaaSStarter {
start(opts?);
handleInvokeWrapper(handlerMapping: string);
}

export interface FunctionHandler {
handler(...args);
Expand Down
150 changes: 86 additions & 64 deletions packages/faas/src/starter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FaaSContext, IFaaSStarter } from './interface';
import { FaaSContext, IFaaSApplication, IFaaSStarter } from './interface';
import { dirname, join, resolve } from 'path';
import {
ContainerLoader,
Expand All @@ -7,9 +7,9 @@ import {
listModule,
listPreloadModule,
MidwayContainer,
MidwayProcessTypeEnum,
MidwayRequestContainer,
REQUEST_OBJ_CTX_KEY,
MidwayProcessTypeEnum,
} from '@midwayjs/core';
import {
APPLICATION_KEY,
Expand Down Expand Up @@ -43,6 +43,7 @@ export class FaaSStarter implements IFaaSStarter {
protected logger;
protected initializeContext;
private lock = new SimpleLock();
private webApplication: IFaaSApplication;

constructor(
options: {
Expand All @@ -53,14 +54,23 @@ export class FaaSStarter implements IFaaSStarter {
preloadModules?: any[];
initializeContext?: object;
logger?: any;
applicationAdapter?: {
getApplication(): IFaaSApplication;
};
} = {}
) {
this.appDir = options.baseDir || process.cwd();
this.globalConfig = options.config || {};
/**
* @deprecated
*/
this.globalMiddleware = options.middleware || [];
this.logger = options.logger || console;
this.baseDir = this.getFaaSBaseDir();
this.initializeContext = options.initializeContext || {};
this.webApplication = this.defineApplicationProperties(
options.applicationAdapter?.getApplication() || {}
);

this.loader = new ContainerLoader({
baseDir: this.baseDir,
Expand Down Expand Up @@ -117,7 +127,7 @@ export class FaaSStarter implements IFaaSStarter {

private registerDecorator() {
this.loader.registerHook(APPLICATION_KEY, () => {
return this;
return this.webApplication;
});
this.loader.registerHook(PLUGIN_KEY, (key, target) => {
const ctx = target[REQUEST_OBJ_CTX_KEY] || {};
Expand Down Expand Up @@ -147,11 +157,9 @@ export class FaaSStarter implements IFaaSStarter {

if (funOptions && funOptions.mod) {
// invoke middleware, just for http
let fnMiddlewere = [];
fnMiddlewere = fnMiddlewere.concat(this.globalMiddleware);
fnMiddlewere = fnMiddlewere.concat(funOptions.middleware);
const fnMiddlewere = [].concat(funOptions.middleware);
if (fnMiddlewere.length) {
const mw: any[] = await this.formatMiddlewares(fnMiddlewere);
const mw: any[] = await this.loadMiddleware(fnMiddlewere);
mw.push(async ctx => {
// invoke handler
const result = await this.invokeHandler(funOptions, ctx, args);
Expand Down Expand Up @@ -251,6 +259,13 @@ export class FaaSStarter implements IFaaSStarter {
// preload init context
await this.getApplicationContext().getAsync(module);
}

// load global web middleware
const globalMW = await this.loadMiddleware(this.globalMiddleware);
for (const mw of globalMW) {
this.webApplication.use(mw as any);
}

// now only for test case
if (typeof opts.cb === 'function') {
await opts.cb();
Expand All @@ -270,78 +285,85 @@ export class FaaSStarter implements IFaaSStarter {
);
}
if (!context.env) {
context.env = this.getEnv();
context.env = this.getApplicationContext()
.getEnvironmentService()
.getCurrentEnvironment();
}
if (!context.logger) {
context.logger = this.logger;
}
return context;
}

private async formatMiddlewares(
middlewares: Array<IMiddleware<FaaSContext>>
) {
const mwArr = [];
for (const mw of middlewares) {
if (typeof mw === 'function') {
mwArr.push(mw);
private defineApplicationProperties(app): IFaaSApplication {
return Object.assign(app, {
getBaseDir: () => {
return this.baseDir;
},

getAppDir: () => {
return this.appDir;
},

getEnv: () => {
return this.getApplicationContext()
.getEnvironmentService()
.getCurrentEnvironment();
},

getConfig: (key?: string) => {
return this.getApplicationContext()
.getConfigService()
.getConfiguration(key);
},

getLogger: () => {
return this.logger;
},

getMidwayType: () => {
return 'MIDWAY_FAAS';
},

getProcessType: () => {
return MidwayProcessTypeEnum.APPLICATION;
},
/**
* return init context value such as aliyun fc
*/
getInitializeContext: () => {
return this.initializeContext;
},

getApplicationContext: () => {
return this.getApplicationContext();
},

useMiddleware: async middlewares => {
const newMiddlewares = await this.loadMiddleware(middlewares);
for (const mw of newMiddlewares) {
this.webApplication.use(mw);
}
},
});
}

private async loadMiddleware(middlewares) {
const newMiddlewares = [];
for (const middleware of middlewares) {
if (typeof middleware === 'function') {
newMiddlewares.push(middleware);
} else {
const middlewareImpl: IMiddleware<FaaSContext> = await this.getApplicationContext().getAsync(
mw
middleware
);
if (middlewareImpl && typeof middlewareImpl.resolve === 'function') {
mwArr.push(middlewareImpl.resolve());
newMiddlewares.push(middlewareImpl.resolve() as any);
}
}
}
return mwArr;
}

/**
* return init context value such as aliyun fc
*/
public getInitializeContext() {
return this.initializeContext;
}

/**
* push middleware to global middleware
* @param mw
*/
public addGlobalMiddleware(mw) {
this.globalMiddleware.push(mw);
}

public getBaseDir(): string {
return this.baseDir;
}

public getAppDir(): string {
return this.appDir;
}

public getEnv(): string {
return this.getApplicationContext()
.getEnvironmentService()
.getCurrentEnvironment();
}

public getConfig(key?: string) {
return this.getApplicationContext()
.getConfigService()
.getConfiguration(key);
}

public getLogger() {
return this.logger;
}

public getMidwayType(): string {
return 'MIDWAY_FAAS';
}

public getProcessType(): MidwayProcessTypeEnum {
return MidwayProcessTypeEnum.APPLICATION;
return newMiddlewares;
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const middleware = ['testMiddlware'];
export const middleware = ['testMiddleware'];
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ export class HelloService implements FunctionHandler {
ctx; // context

handler(event) {
return event.text + this.ctx.text + this.ctx.requestId;
return this.ctx.originContext['text'] + event.text + this.ctx.requestId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Provide } from '@midwayjs/decorator';
import * as assert from 'assert';

@Provide()
export class TestMiddlware {
export class TestMiddleware {
resolve() {
return async (ctx, next) => {
assert(ctx.logger);
Expand Down
13 changes: 11 additions & 2 deletions packages/faas/test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,16 +159,25 @@ describe('test/index.test.ts', () => {
});

it('test custom global middleware', async () => {
const { start } = require('../../serverless-scf-starter/src');
const runtime = await start();
const starter = new FaaSStarter({
baseDir: join(__dirname, './fixtures/base-app-middleware'),
applicationAdapter: runtime,
});
await starter.start();
const data = await starter.handleInvokeWrapper('index.handler')(
const data = await runtime.asyncEvent(
starter.handleInvokeWrapper('index.handler')
)(
{
text: 'hello',
httpMethod: 'GET',
headers: {},
requestContext: {},
},
{ text: 'a' }
);
assert(data === 'ahello555');

assert(data.body === 'ahello555');
});
});
Loading

0 comments on commit 364d62b

Please sign in to comment.