How do I use database entities in middleware?

Viewed 532

// location.entity.ts

import {Entity, Column, PrimaryGeneratedColumn, CreateDateColumn} from 'typeorm'

@Entity('location')
export class Location {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({length: 500})
  name: string;

  @Column('text')
  desc: string;

  @CreateDateColumn({type: 'timestamp'})
  date: number;
}

// black.middleware.ts

import {Injectable, NestMiddleware} from '@nestjs/common'
import {Response, Request} from 'express'
import {InjectRepository} from '@nestjs/typeorm'
import {Location} from 'src/location/location.entity'
import {Repository} from 'typeorm'
@Injectable()
export class BlackMiddleware implements NestMiddleware {
  constructor(@InjectRepository(Location) private locationRepository: Repository<Location>) {
  }
  use(req: Request, res: Response, next: () => void): any {
    console.log(this.locationRepository, 'aaa');
    return true;
  }
}

In middleware, I want to use some other dependency injection, either entity, so how do I refer to it correctly?

// app.module.ts

...
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer): any {
    consumer.apply(BlackMiddleware).forRoutes('*')
  }
}

Expect typeorm to be used in the middleware, but I don't know how to resolve the dependency. Is the middleware being used globally

If used in this way, an error will be reported:

[Nest] 56559   - 2020/12/25 上午11:43:08   [ExceptionHandler] Nest can't resolve dependencies of the BlackMiddleware (?). Please make sure that the argument LocationRepository at index [0] is available in the BlackMiddleware context.

Potential solutions:
- If LocationRepository is a provider, is it part of the current BlackMiddleware?
- If LocationRepository is exported from a separate @Module, is that module imported within BlackMiddleware?
  @Module({
    imports: [ /* the Module containing LocationRepository */ ]
  })
 +0ms
Error: Nest can't resolve dependencies of the BlackMiddleware (?). Please make sure that the argument LocationRepository at index [0] is available in the BlackMiddleware context.

Potential solutions:
- If LocationRepository is a provider, is it part of the current BlackMiddleware?
- If LocationRepository is exported from a separate @Module, is that module imported within BlackMiddleware?
  @Module({
    imports: [ /* the Module containing LocationRepository */ ]
  })

    at Injector.lookupComponentInParentModules (/Users/brian/code/node/nest/learn-nest/node_modules/@nestjs/core/injector/injector.js:192:19)
    at async Injector.resolveComponentInstance (/Users/brian/code/node/nest/learn-nest/node_modules/@nestjs/core/injector/injector.js:148:33)
    at async resolveParam (/Users/brian/code/node/nest/learn-nest/node_modules/@nestjs/core/injector/injector.js:102:38)
    at async Promise.all (index 0)
    at async Injector.resolveConstructorParams (/Users/brian/code/node/nest/learn-nest/node_modules/@nestjs/core/injector/injector.js:117:27)
    at async Injector.loadInstance (/Users/brian/code/node/nest/learn-nest/node_modules/@nestjs/core/injector/injector.js:81:9)
    at async Injector.loadProvider (/Users/brian/code/node/nest/learn-nest/node_modules/@nestjs/core/injector/injector.js:38:9)
    at async Promise.all (index 0)
    at async InstanceLoader.createInstancesOfProviders (/Users/brian/code/node/nest/learn-nest/node_modules/@nestjs/core/injector/instance-loader.js:43:9)
    at async /Users/brian/code/node/nest/learn-nest/node_modules/@nestjs/core/injector/instance-loader.js:28:13
    at async Promise.all (index 26)
    at async InstanceLoader.createInstances (/Users/brian/code/node/nest/learn-nest/node_modules/@nestjs/core/injector/instance-loader.js:27:9)
    at async InstanceLoader.createInstancesOfDependencies (/Users/brian/code/node/nest/learn-nest/node_modules/@nestjs/core/injector/instance-loader.js:17:9)
    at async /Users/brian/code/node/nest/learn-nest/node_modules/@nestjs/core/nest-factory.js:90:17
    at async Function.asyncRun (/Users/brian/code/node/nest/learn-nest/node_modules/@nestjs/core/errors/exceptions-zone.js:18:13)
    at async NestFactoryStatic.initialize (/Users/brian/code/node/nest/learn-nest/node_modules/@nestjs/core/nest-factory.js:88:13)

How do I properly use other dependency injection (such as database) in middleware?

1 Answers

Maybe you could try service just like controller. Let the logic be handled at the service layer.

for example:

import { Injectable, Logger, NestMiddleware } from '@nestjs/common';
import { NextFunction, Request, Response } from 'express';
import * as requestIp from 'request-ip';
import { LoggerService } from 'src/logger/logger.service';

@Injectable()
export class HttpLoggerMiddleware implements NestMiddleware {
  constructor(private readonly loggerService: LoggerService) {}

  private logger = new Logger();

  use(request: Request, response: Response, next: NextFunction): void {
    const { ip, method, originalUrl } = request;

    const clientIp = requestIp.getClientIp(request);
    const msg = `${method} ${originalUrl} ${clientIp} ${ip} `;
    this.logger.log(msg);

    this.loggerService.create({
      ip: clientIp,
      originalUrl,
    });

    next();
  }
}

Related