请求、响应、应用
Midway 框架会根据不同的场景来启动不同的应用,前文提到,我们默认选用 EggJS 作为我们的 Web 框架,也可以使用 Express 或者 Koa。
每个使用的 Web 框架会提供自己独特的能力,这些独特的能力都会体现在各自的 请求和响应(Context)和 应用(Application)之上。
上下文和应用定义约定
为了简化使用,所有的上层框架导出 请求和响应(Context)和 应用(Application)定义,我们都保持一致。即 Context
和 Application
。
import { Application, Context } from 'egg';
import { Application, Context } from '@midwayjs/koa';
import { Application, Context } from '@midwayjs/express';
且非 Web 框架,我们也保持了一致。
import { Application, Context } from '@midwayjs/socketio';
import { Application, Context } from '@midwayjs/grpc';
import { Application, Context } from '@midwayjs/rabbitmq';
请求和响应
每个 Web 框架的请求和响应对象是不同的,EggJS 和 Koa 都是使用 ctx
对象,而 Express 使用 req
, res
对象。
在 Midway 提供的装饰器不够,或者需要复杂业务逻辑的时候,我们就需要原生框架的对象支持。
在 默认的请求作用域 中,也就是说在 控制器(Controller)或者普通的 服务(Service)中,我们可以使用 @Inject
来注入对应的实例。
比如在以 EggJS 为上层 Web 框架代码中,我们可以这样获取到对应的 ctx 实例。
import { Inject, Controller, Get, Provide } from '@midwayjs/decorator';
import { Context } from 'egg';
@Provide()
@Controller('/')
export class HomeController {
@Inject()
ctx: Context;
@Get('/')
async home() {
// this.ctx.query
}
}
而 Koa 和 Express 则是不同的用法。Koa 示例如下。
import { Inject, Controller, Get, Provide } from '@midwayjs/decorator';
import { Context } from '@midwayjs/koa';
@Provide()
@Controller('/')
export class HomeController {
@Inject()
ctx: Context;
@Get('/')
async home() {
// this.ctx.query
}
}
Express 比较特殊, @Inject
注入的 ctx 对象由 Midway 做了封装,为 Express 的 req 对象和 res 对象的集合。
import { Inject, Controller, Get, Provide } from '@midwayjs/decorator';
import { Context } from '@midwayjs/express';
import { Request, Response } from 'express';
@Provide()
@Controller('/')
export class HomeController {
@Inject()
ctx: Context; // 包含了 req 和 res
@Inject()
req: Request;
@Inject()
res: Response;
@Get('/')
async home() {
// this.req.query
}
}
应用实例
在编写业务代码中,有时候我们需要用到原本框架的能力,而这些能力可能暴露在各自的 app 对象之上。Midway 提供了 @App
这个装饰器,用于注入当前运行时的 app 示例。
比如,在 EggJS 框架中,app 提供了 curl
方法,用于获取远程的数据,我们通过注入这个 app 就可以拿到对应的方法。
import { App, Controller, Get, Provide } from '@midwayjs/decorator';
import { Application } from 'egg';
@Provide()
@Controller('/')
export class HomeController {
@App()
app: Application;
@Get('/')
async home() {
const data = await this.app.curl('/api/data.json');
return {
data,
};
}
}
我们在任意的 @Provide
装饰的 Class 上都可以使用 @App
装饰器。
而在 Koa 为 Web 框架的应用上,将会注入 Koa 的 app 实例。
import { App, Controller, Get, Provide } from '@midwayjs/decorator';
import { Application } from '@midwayjs/koa';
@Provide()
@Controller('/')
export class HomeController {
@App()
app: Application;
@Get('/')
async home() {
// this.app.use(xxx)
}
}
这里的 Application 定义是由于 Koa 不支持直接扩展,Midway 为了方便使用,进行了封装。
具体的 app 上的方法,请参考详细 app API 或者不同的 Web 框架文档。