如何解决Loopback 4中间件未注册
我正在遵循此example here进行简单的日志记录中间件设置。但是我似乎无法获取它来记录我的请求信息。当我按下/ping
时,我得到标准响应,但是没有任何内容注销到控制台。
我尝试在两个不同的位置注册中间件。 index.ts
和application.ts
。
// src/middleware/log.middleware.ts
import { Next } from '@loopback/core'
import { Middleware,MiddlewareContext } from '@loopback/rest'
export const testLoggingMiddleware: Middleware = async (
middlewareCtx: MiddlewareContext,next: Next,) => {
const { request } = middlewareCtx
console.log('Request: %s %s',request.method,request.originalUrl)
try {
// Proceed with next middleware
await next()
// Process response
console.log('Response received for %s %s',request.originalUrl)
} catch (err) {
// Catch errors from downstream middleware
console.error('Error received for %s %s',request.originalUrl)
throw err
}
}
// src/index.ts
import { ApplicationConfig,RemoteConfigurationsApplication } from './application'
import { testLoggingMiddleware } from './middleware/log.middleware'
import { NodeEnvironmentService } from './services'
export * from './application'
export async function main(
options: ApplicationConfig = {},): Promise<RemoteConfigurationsApplication> {
const app = new RemoteConfigurationsApplication(options)
app.middleware(testLoggingMiddleware) // trying to add the middleware here as well
await app.boot()
await app.start()
const url = app.restServer.url
console.log(`Server is running at ${url}`)
console.log(`Try ${url}/ping`)
return app
}
if (require.main === module) {
// Run the application
const config = {
rest: {
port: +(process.env.PORT ?? 8081),host: process.env.HOST,// The `gracePeriodForClose` provides a graceful close for http/https
// servers with keep-alive clients. The default value is `Infinity`
// (don't force-close). If you want to immediately destroy all sockets
// upon stop,set its value to `0`.
// See https://www.npmjs.com/package/stoppable
gracePeriodForClose: 5000,// 5 seconds
openApiSpec: {
// useful when used with OpenAPI-to-GraphQL to locate your application
setServersFromRequest: true,},basePath: `/`,cors: {
origin: '*',methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',preflightContinue: false,optionsSuccessStatus: 204,credentials: true,}
main(config).catch((err) => {
console.error('Cannot start the application.',err)
process.exit(1)
})
}
// src/application.ts
require('dotenv').config()
import { BootMixin } from '@loopback/boot'
import { ApplicationConfig } from '@loopback/core'
import { HealthComponent } from '@loopback/extension-health'
import { RestExplorerBindings,RestExplorerComponent } from '@loopback/rest-explorer'
import { RepositoryMixin } from '@loopback/repository'
import { RestApplication } from '@loopback/rest'
import { ServiceMixin } from '@loopback/service-proxy'
import * as path from 'path'
import { testLoggingMiddleware } from './middleware/log.middleware'
import { MySequence } from './sequence'
export { ApplicationConfig }
export class RemoteConfigurationsApplication extends BootMixin(
ServiceMixin(RepositoryMixin(RestApplication)),) {
constructor(options: ApplicationConfig = {}) {
super(options)
// Set up the custom sequence
this.sequence(MySequence)
// Set up default home page
this.static('/',path.join(__dirname,'../public'))
// Customize @loopback/http-explorer configuration here
this.configure(RestExplorerBindings.COMPONENT).to({
path: '/explorer',})
this.component(RestExplorerComponent)
this.component(HealthComponent)
this.middleware(testLoggingMiddleware) // adding middleware in application
this.projectRoot = __dirname
// Customize @loopback/boot Booter Conventions here
this.bootOptions = {
controllers: {
// Customize ControllerBooter Conventions here
dirs: ['controllers'],extensions: ['.controller.js'],nested: true,}
}
}
解决方法
使用您的中间件,我可以在控制台上看到日志,按照 @Varun 建议将 MySequence 类替换为以下代码后,您可以获得更多详细信息 here
import { MiddlewareSequence } from '@loopback/rest';
export class MySequence extends MiddlewareSequence {}
为了能够向客户端发送响应,您需要从中间件返回 await next()
export const testLoggingMiddleware: Middleware = async (
middlewareCtx: MiddlewareContext,next: Next,) => {
const {request} = middlewareCtx
console.log('Request: %s %s',request.headers,request.method,request.originalUrl)
try {
// Proceed with next middleware
const result = await next()
// Process response
console.log('Response received for %s %s',request.originalUrl)
return result
} catch (err) {
// Catch errors from downstream middleware
console.error('Error received for %s %s',request.originalUrl)
throw err
}
}
,
如果有人仍然遇到这个问题,这对我有用:
- 更新您的 sequence.ts 使其看起来像这样:
import { MiddlewareSequence } from '@loopback/rest';
export class MySequence extends MiddlewareSequence {}
- 在 /src/middleware/example.middleware.ts 上创建中间件
import { Next } from '@loopback/core'
import { Middleware,MiddlewareContext } from '@loopback/rest'
export const exampleMiddleware: Middleware = async (
middlewareCtx: MiddlewareContext,request.originalUrl)
throw err
}
}
- 在 application.ts 中注册您的中间件
import {ApplicationConfig} from '@loopback/core';
import {RestApplication} from '@loopback/rest';
import {exampleMiddleware} from './middleware/example.middleware';
export class MyApplication extends RestApplication {
constructor(config: ApplicationConfig) {
// register your middleware
this.middleware(exampleMiddleware);
}
}
- 运行应用并检查您的控制台。
如@Rifa所述,您需要更新MySequence
类
之前,它具有以下内容-
import { inject } from '@loopback/context';
import {
FindRoute,InvokeMethod,ParseParams,Reject,RequestContext,RestBindings,Send,SequenceHandler,InvokeMiddleware
} from '@loopback/rest';
const SequenceActions = RestBindings.SequenceActions;
export class MySequence implements SequenceHandler {
/**
* Optional invoker for registered middleware in a chain.
* To be injected via SequenceActions.INVOKE_MIDDLEWARE.
*/
@inject(SequenceActions.INVOKE_MIDDLEWARE,{ optional: true })
protected invokeMiddleware: InvokeMiddleware = () => false;
constructor(
@inject(SequenceActions.FIND_ROUTE) protected findRoute: FindRoute,@inject(SequenceActions.PARSE_PARAMS) protected parseParams: ParseParams,@inject(SequenceActions.INVOKE_METHOD) protected invoke: InvokeMethod,@inject(SequenceActions.SEND) public send: Send,@inject(SequenceActions.REJECT) public reject: Reject
) {}
async handle(context: RequestContext) {
try {
const { request,response } = context;
// Invoke registered Express middleware
const finished = await this.invokeMiddleware(context);
if (finished) {
// The response been produced by the middleware chain
return;
}
const route = this.findRoute(request);
const args = await this.parseParams(request,route);
const result = await this.invoke(route,args);
this.send(response,result);
} catch (err) {
this.reject(context,err);
}
}
}
替换为-
import { MiddlewareSequence } from '@loopback/rest';
export class MySequence extends MiddlewareSequence {}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。