跳到主要内容
版本:3.0.0

内置服务

在 Midway 中,提供了众多的内置对象,方便用户使用。

在本章节,我们会介绍和框架相关联的的 Application,Context 对象,Midway 默认容器上的一些服务对象,这些对象在整个业务的开发中都会经常遇到。

以下是一些 Midway 依赖注入容器内置的服务,这些服务由依赖注入容器初始化,在业务中全局可用。

MidwayApplicationManager

Midway 内置的应用管理器,可以使用它获取到所有的 Application。

可以通过注入获取,比如对不同的 Application 添加同一个中间件。

import { MidwayApplicationManager, onfiguration, Inject } from '@midwayjs/core'
import { CustomMiddleware } from './middleware/custom.middleware';

@Configuration({
// ...
})
export class MainConfiguration {
@Inject()
applicationManager: MidwayApplicationManager;

async onReady() {
this.applicationManager
.getApplications(['koa', 'faas', 'express', 'egg'])
.forEach(app => {
app.useMiddleware(CustomMiddleware);
});
}
}

API返回类型描述
getFramework(namespace: string)IMidwayFramework返回参数指定的 framework
getApplication(namespace: string)IMidwayApplication返回参数指定的 Application
getApplications(namespace: string[])IMidwayApplication[]返回参数指定的多个 Application
getWebLikeApplication()IMidwayApplication[]返回类似 Web 场景的 Application(express/koa/egg/faas)

MidwayInformationService

Midway 内置的信息服务,提供基础的项目数据。

可以通过注入获取。

import { Inject, Controller, Get, MidwayInformationService } from '@midwayjs/core';

@Controller('/')
export class HomeController {

@Inject()
informationService: MidwayInformationService;

@Get('/')
async home() {
// this.informationService.getAppDir();
}
}

一般用来返回用户相关的目录。

API返回类型描述
getAppDir()String返回应用根目录
getBaseDir()String返回应用代码目录,默认本地开发为 src,服务器运行为 dist
getHomeString返回机器用户目录,指代 ~ 的地址。
getPkgObject返回 package.json 的内容
getRootString在开发环境,返回 appDir,在其他环境,返回 Home 目录

MidwayEnvironmentService

Midway 内置的环境服务,提供环境设置和判断。

可以通过注入获取。

import { Inject, Controller, Get, MidwayEnvironmentService } from '@midwayjs/core';

@Controller('/')
export class HomeController {

@Inject()
environmentService: MidwayEnvironmentService;

@Get('/')
async home() {
// this.environmentService.getCurrentEnvironment();
}
}

一般用来获取当前的环境,API 如下:

API返回类型描述
getCurrentEnvironment()String返回应用当前环境
setCurrentEnvironment()设置当前环境
isDevelopmentEnvironmentBoolean判断是否是开发环境

MidwayConfigService

Midway 内置的多环境配置服务,提供配置的加载,获取,它也是 @Config 装饰器的数据源。

可以通过注入获取。

import { Inject, Controller, Get, MidwayConfigService } from '@midwayjs/core';

@Controller('/')
export class HomeController {

@Inject()
configService: MidwayConfigService;

@Get('/')
async home() {
// this.configService.getConfiguration();
}
}

一般用来获取当前的配置,API 如下:

API返回类型描述
addObject(obj)动态添加配置对象
getConfiguration()Object返回当前合并好的配置对象
clearAllConfig()清空所有配置

MidwayLoggerService

Midway 内置的日志服务,提供日志创建,获取等 API,它也是 @Logger 装饰器的数据源。

可以通过注入获取。

import { Inject, Controller, Get, MidwayLoggerService } from '@midwayjs/core';

@Controller('/')
export class HomeController {

@Inject()
loggerService: MidwayLoggerService;

@Get('/')
async home() {
// this.loggerService.getLogger('logger');
}
}

一般用来获取日志对象,API 如下:

API返回类型描述
createInstance(name, config)ILogger动态创建一个 Logger 实例
getLogger(name)ILogger根据日志名返回一个 Logger 实例

MidwayFrameworkService

Midway 内置的自定义框架服务,配合组件中自定义的 @Framework 标记的 Class,提供不同协议的对外服务。

可以通过注入获取。

import { Inject, Controller, Get, MidwayFrameworkService } from '@midwayjs/core';

@Controller('/')
export class HomeController {

@Inject()
frameworkService: MidwayFrameworkService;

@Get('/')
async home() {
// this.frameworkService.getMainFramework();
}
}

一般用来获取 Framework 对象,API 如下:

API返回类型描述
getMainFramework()IMidwayFramework返回主框架实例
getMainApp()IMidwayApplication返回主框架中的 app 对象
getFramework(nameOrFrameworkType)IMidwayFramework根据框架名或者框架类型返回框架实例

MidwayMiddlewareService

Midway 内置的中间件处理服务,用于自建中间件的处理。

Midway 内置的自定义装饰器服务,用于实现框架层面的自定义装饰器,一般在自定义框架时使用。

可以通过注入获取。

import { Inject, Controller, Get, MidwayMiddlewareService } from '@midwayjs/core';

@Controller('/')
export class HomeController {

@Inject()
middlewareService: MidwayMiddlewareService;

@Get('/')
async home() {
// this.middlewareService.compose(/** 省略 **/);
}
}

API 如下:

API返回类型描述
compose(middlewares, app, name?)IMiddleawre将多个中间件数组组合到一起返回一个新的中间件

MidwayDecoratorService

Midway 内置的自定义装饰器服务,用于实现框架层面的自定义装饰器。

可以通过注入获取。

import { Inject, Controller, Get, MidwayDecoratorService } from '@midwayjs/core';

@Controller('/')
export class HomeController {

@Inject()
decoratorService: MidwayDecoratorService;

@Get('/')
async home() {
// this.decoratorService.registerPropertyHandler(/** 省略 **/);
}
}

API 如下:

API返回类型描述
registerPropertyHandler(decoratorKey, handler)添加一个属性装饰器实现
registerMethodHandler(decoratorKey, handler)添加一个方法装饰器实现
registerParameterHandler(decoratorKey, handler)添加一个参数装饰器实现

具体示例,请参考 自定义装饰器 部分。

MidwayAspectService

Midway 内置的拦截器服务,用于加载 @Aspect 相关的能力,自定义装饰器也使用了该服务。

可以通过注入获取。

import { Inject, Controller, Get, MidwayAspectService } from '@midwayjs/core';

@Controller('/')
export class HomeController {

@Inject()
aspectService: MidwayAspectService;

@Get('/')
async home() {
// this.aspectService.interceptPrototypeMethod(/** 省略 **/);
}
}

API 如下:

API返回类型描述
addAspect(aspectInstance, aspectData)添加一个拦截器实现
interceptPrototypeMethod(Clazz, methodName, aspectObject: IMethodAspect)拦截原型上的方法,将拦截器的实现添加上去

MidwayLifeCycleService

Midway 内置的生命周期运行服务,用于运行 configuration 中的生命周期。

该服务均为内部方法,用户无法直接使用。

MidwayMockService

Midway 内置的数据模拟服务,用于在开发和单测时模拟数据。

可以通过注入获取。

import { Inject, Controller, Get, MidwayMockService } from '@midwayjs/core';

@Controller('/')
export class HomeController {

@Inject()
mockService: MidwayMockService;

@Get('/')
async home() {
// this.mockService.mockProperty(/** 省略 **/);
}
}

API 如下

API返回类型描述
mockClassProperty(clzz, propertyName, value)mock 一个class 上的属性(方法 )
mockProperty(obj, key, value)mock 一个普通对象上的属性(方法 )
mockContext(app, key, vlue)mock 上下文对象上的属性
restore()清空所有 mock 数据

mockClassProperty

用于模拟类的某个属性或者方法。

比如某个类。

@Provide()
export class UserService {
data;

async getUser() {
return 'hello';
}
}

我们也可以在代码中模拟。


import { MidwayMockService, Provide, Inject } from '@midwayjs/core';

@Provide()
class TestMockService {
@Inject()
mockService: MidwayMockService;

mock() {
// 模拟方法
this.mockService.mockClassProperty(UserService, 'getUser', async () => {
return 'midway';
});

// 模拟属性
this.mockService.mockClassProperty(UserService, 'data', {
bbb: '1'
});
}
}

mockProperty

使用 mockProperty 方法来模拟对象的属性。

import { MidwayMockService, Provide, Inject } from '@midwayjs/core';

@Provide()
class TestMockService {
@Inject()
mockService: MidwayMockService;

mock() {
const a = {};
// 模拟属性
this.mockService.mockProperty(a, 'name', 'hello');
// a['name'] => 'hello'

// 模拟方法
this.mockService.mockProperty(a, 'getUser', async () => {
return 'midway';
});
// await a.getUser() => 'midway'
}
}

mockContext

由于 Midway 的 Context 和 app 关联,所以在模拟的时候需要传入 app 实例。

使用 mockContext 方法来模拟上下文。

import { MidwayMockService, Configuration, App } from '@midwayjs/core';

@Configuration(/**/)
export class MainConfiguration {
@Inject()
mockService: MidwayMockService;

@App()
app;

async onReady() {
// 模拟上下文
mockContext(app, 'user', 'midway');
}
}

// ctx.user => midway

如果你的数据比较复杂,或者带有逻辑,也可以使用回调形式。

import { MidwayMockService, Configuration, App } from '@midwayjs/core';

@Configuration(/**/)
export class MainConfiguration {
@Inject()
mockService: MidwayMockService;

@App()
app;

async onReady() {
// 模拟上下文
mockContext(app, (ctx) => {
ctx.user = 'midway';
});
}
}

// ctx.user => midway

注意,这个 mock 行为是在所有中间件之前执行。

MidwayWebRouterService

Midway 内置的路由表服务,用于应用路由和函数的创建。

可以通过注入获取。

import { MidwayWebRouterService, Configuration, Inject } from '@midwayjs/core';

@Configuration({
// ...
})
export class MainConfiguration {
@Inject()
webRouterService: MidwayWebRouterService;

async onReady() {
this.webRouterService.addRouter(async (ctx) => {
return 'hello world';
}, {
url: '/',
requestMethod: 'GET',
});
}
}

API 如下

API返回类型描述
addController(controllerClz, controllerOption)动态添加一个 Controller
addRouter(routerFunction, routerInfoOption)动态添加一个路由函数
getRouterTable()Promise<Map<string, RouterInfo[]>>获取带层级的路由
getFlattenRouterTable()Promise<RouterInfo[]>获取扁平化路由列表
getRoutePriorityList()Promise<RouterPriority[]>获取路由前缀列表
getMatchedRouterInfo(url: string, method: string)Promise<RouterInfo | undefined>根据访问的路径,返回当前匹配的路由信息

更多使用请参考 Web 路由表

MidwayServerlessFunctionService

Midway 内置的函数信息服务,继承与 MidwayWebRouterService ,方法几乎相同。

可以通过注入获取。

import { MidwayServerlessFunctionService, Configuration, Inject } from '@midwayjs/core';

@Configuration({
// ...
})
export class MainConfiguration {
@Inject()
serverlessFunctionService: MidwayServerlessFunctionService;

async onReady() {
this.serverlessFunctionService.addServerlessFunction(async (ctx, event) => {
return 'hello world';
}, {
type: ServerlessTriggerType.HTTP,
metadata: {
method: 'get',
path: '/api/hello'
},
functionName: 'hello',
handlerName: 'index.hello',
});
}
}

API 如下

API返回类型描述
addServerlessFunction(fn, triggerOptions, functionOptions)动态添加一个函数
getFunctionList()Promise<RouterInfo[]>获取所有函数列表

更多使用请参考 Web 路由表

MidwayHealthService

Midway 内置的健康检查执行服务,用于外部扩展的健康检查能力。

完整的健康检查包含两个部分:

  • 1、健康检查的触发端,比如外部的定时请求,通常为一个 Http 接口
  • 2、健康检查的执行端,一般在各个组件或者业务中,检查特定的项是否正常

MidwayHealthService 一般用于健康检查的触发端,下面描述的内容一般在触发端会实现。

可以通过注入获取后,执行健康检查任务。

import { MidwayHealthService ,Configuration, Inject } from '@midwayjs/core';

@Configuration({
// ...
})
export class MainConfiguration {
@Inject()
healthService: MidwayHealthService;

async onServerReady() {
setInterval(() => {
const results = await this.healthService.getStatus();

// console.log(results);
// =>
// {
// "status": false
// "namespace": "redis",
// "reason": "health check timeout",
// "results": [
// {
// "status": false
// "reason": "health check timeout",
// "namespace": "redis"
// }
// ]
// }

}, 1000);
// ...
}
}

API 如下

API返回类型描述
getStatus()Promise<HealthResults>动态添加一个函数
setCheckTimeout(timeout: number)void设置超时时间

getStatus 方法用于外部调用轮询 configuration 中的 onHealthCheck 方法,返回一个符合 HealthResults 结构的数据。

HealthResults 包含几个字段,status 表示本次检查是否成功, 如果失败,reason 表示本次第一个失败组件的原因,namespace 代表第一个失败的组件名, results 则表示本次检查所有的返回项内容,返回项的结构和外部相同。

在执行过程时,如果 onHealthCheck 方法出现下列的情况,都会标记为失败。

  • 1、未返回符合 HealthResult 结构的数据
  • 2、未返回值
  • 3、执行超时
  • 4、抛出错误
  • 5、返回符合 HealthResult 结构的代表错误的数据,比如 {status: false}

健康检查默认等待超时时间 1s。

可以使用全局的配置进行覆盖。

// config.default
export default {
core: {
healthCheckTimeout: 2000,
}
};

健康检查的执行端在业务或者组件的生命周期中实现,具体请查看 生命周期