Follow the documentation to learn how to use Web middleware

What is Web middleware

Web middleware is a function that is called (partly) before and after the controller is called. Request and response objects can be accessed by middleware functions.

Different upper-layer Web frameworks have different middleware forms. The middleware form of EggJS is the same as that of Koa, which is based on the onion ring model. Express is a traditional queue model.

The role of Web middleware

The Midway defined Web middleware is similar to the interception I used with KOA, and it is very convenient to implement the post-processing logic.

For example:

Global interception is used in KOA to determine whether the token carried in the request header is correct

app.use(async (ctx, next) => {
    let url = ctx.request.url
    list.forEach((item,index) = >{if(item.name === url){ key=index }})
    if(! ~key){ list.push({name:ctx.request.url,count:1});
        if( url === '/login') {await next()
        }else{
            let token = ctx.request.header.token||[]
            let user = await tools.search(User,{token},"all")
            if(user.length){
                await next()
            }else{
                ctx.body = {
                    "retCode": false."resultMsg": 'Login has expired, please try again'."errorCode": 3}}}}else{
        if( url === '/login') {await next()
        }else{
            let token = ctx.request.header.token||[]
            let user = await tools.search(User,{token},"all")
            if(user.length){
                await next()
            }else{
                ctx.body = {
                    "retCode": false."resultMsg": 'Login has expired, please try again'."errorCode": 3}}}}})Copy the code

Midway’s Web middleware is illustrated with official examples

export class TokenMiddleware implements IWebMiddleware {
  resolve() {
    return async (ctx: Context, next: IMidwayWebNext) => {
      // Logic executed before the controller
      const startTime = Date.now();
      ctx.body = { name:false }
      // Execute the next Web middleware, and finally the controller
      // await next();
      // Logic executed after the controller
      console.log(Date.now() - startTime); }; }}Copy the code

Await next() controls whether or not to execute the controller. In terms of usage, it is an encapsulation of Generator functions. Yield contains the controller.

Note: TokenMiddleware is used with a lowercase hump for the following reasons

Key Attribute Description

service

The process of using a service is divided into several parts:

  • 1. Expose your service using the @provide decorator

  • Inject your service with the @inject decorator at the point of the calling code

  • 3. Invoke the injection service and execute the corresponding method

Midway’s core dependency Injection container automatically associates your controllers and services, initializing all code as it runs. You don’t need to manually initialize classes.

Description of injection Behavior

The Provide decorator does:

  • 1. This Class, hosted by the DEPENDENCY injection container, is automatically instantiated (new).
  • This Class can be injected by other classes in the container

The corresponding @inject decorator does the following:

  • 1. In the dependency injection container, find the corresponding attribute name and assign it to the corresponding instantiated object

The @provide and @inject decorators take arguments, and they come in pairs.

This parameter is called the dependency injection identifier, which is replaced by key. This is where the default Midwayde behavior comes in. By default:

  • 1.@Provide 取 The hump string of the class nameAs a key
  • 2,@InjectAccording to theThe rulesTo get the key

The rules are as follows:

  • 1. If the decorator contains an argument, the argument string is used as the key

  • If the annotated TS type is Class, then the key of the @provide Class is used as the key

  • 3. If there are no parameters and the TS type is not Class, the attribute name is used as the key

They can be correlated if they are consistent with each other.

export interface IService { }
// service
@Provide(a)// The exposed key is userServiceexport
// Key@provide ('testService') can also be customized, but @inject is required
class UserService implements IService {
    / /...
}
// controller 
@Provide(a)@Controller('/api/user')
export class APIController {

@Inject('userService')
@provide @inject ('testService')
userService1: UserService;// The injected key is userService

@Inject(a)userService2: UserService;

@Inject(a)userService: IService;
}
Copy the code

conclusion

// middleware
export class TokenMiddleware implements IWebMiddleware {
  resolve() {
    return async (ctx: Context, next: IMidwayWebNext) => {
      // Logic executed before the controller
      const startTime = Date.now();
      ctx.body = { name:false }
      // Execute the next Web middleware, and finally the controller
      // await next();
      // Logic executed after the controller
      console.log(Date.now() - startTime); }; }}/ / when used
@Get('/', { middleware: [ 'tokenMiddleware' ]})
async home() {}
Copy the code