快速路由内的访问模型方法环回4

问题描述

我将向您展示我正在尝试做的事的一个例子:

server.ts

export class ExpressServer {
  public readonly app: express.Application;
  public readonly lbApp: ImportedApp;
  private server?: Server;

  constructor(options: ApplicationConfig = {}) {
    this.app = express();
    this.lbApp = new ImportedApp(options);
    this.app.get('/hello',async function (_req: Request,res: Response) {
      //Here i'd like to call a model like User.findById() but can't figure out how to do it..
    });

  }
}

正如您在评论中看到的那样,我正在尝试访问我的模型方法以在路线中使用它们(就像在视图中显示用户信息一样),但无法弄清楚该怎么做。我已经尝试导入数据源,模型,控制器,但是什么都不包含我的方法(FindById,创建等)。

如果我什么也没找到,我将不得不使用AxiosRequest之类的东西来从api请求资源,而不是在我的代码中之类的await request('api/users/myusername)

解决方法

在LoopBack 4中,我们使用存储库设计模式来访问数据。为了通过其ID查找用户实例,您需要通过依赖注入获得UserRepository的实例。引用https://loopback.io/doc/en/lb4/Repository.html

存储库正在向模型添加行为。模型描述数据的形状,存储库提供类似于CRUD操作的行为。这与LoopBack 3.x(模型也实现行为)不同。

更新的解决方案

要获取Repository类的实例,可以使用Service Locator设计模式,并从LoopBack的REST层提供的每个请求Context对象中获取实例。

import {MIDDLEWARE_CONTEXT,RequestContext} from '@loopback/rest';
import {UserRepository} from '../repositories';

function expressHandler(req,res,next) {
  const ctx = (req as any)[MIDDLEWARE_CONTEXT];  
  const userRepo = await ctx.get<UserRepository>('repositories.UserRepository');
  const users = await userRepo.find({limit: 10});
  // render your view
}

我们正在讨论如何使该用例更易于在GitHub pull request loopback-next#6793中实现,欢迎随时加入讨论。

原始答案

我建议您编写一个LoopBack 4控制器,而不是为呈现的页面编写Express路由。并注入Express Response对象,以允许您呈现HTML视图,如https://loopback.io/doc/en/lb4/Accessing-http-request-response.html#inject-http-response

中所述
import {Response,RestBindings,oas} from '@loopback/rest';
import {inject} from '@loopback/core';
import {UserRepository} from '../repositories';

export class PingController {
  constructor(
    @inject(RestBindings.Http.RESPONSE) 
    private response: Response

    @repository(UserRepository)
    public userRepository: UserRepository,) {}

  // Hide this endpoint from OpenAPI spec generated for the app
  @oas.visibility('undocumented')
  @get('/users')
  list(): Response {
    // Access User data via this.userRepository API
    const users = await this.userRepository.find({limit: 10});

    // Access the response object via `this.response`
    this.response.render('users',{users});

    // Return the HTTP response object so that LoopBack framework skips the
    // generation of HTTP response
    return this.response;
  }
}

话虽如此,如果您已经知道如何在Express路由中从LB4应用访问数据源实例,那么您也可以从路由中手动实例化存储库类:

const db = // your datasource

this.app.get('/hello',async function (_req: Request,res: Response) {
  const repo = new UserRepository(db);
  const users = await this.userRepository.find({limit: 10});
});
,

对我来说,解决方案不起作用。从 express-composition 示例开始,我只需要从 lb4 请求处理程序外部的通用快速路由访问 lb 存储库:

constructor(options: ApplicationConfig = {}) {
  this.app = express();
  this.lbApp = new NoteApplication(options);
  this.lbApp.basePath('')

  // Expose the front-end assets via Express,not as LB4 route
  this.app.use('/api',this.lbApp.requestHandler);

  this.app.get('/hello',async (req: Request,res: Response) => {
    const ctx = (req as any)[MIDDLEWARE_CONTEXT];
    const userRepo = await ctx.get('repositories.UserRepository');
    res.send('Hello world!');
  });
}

行中的ctx

const ctx = (req as any)[MIDDLEWARE_CONTEXT];

总是未定义的。

我的主要目标是让路由不在 /api 下仍然可以访问 lb4 存储库。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...