在 Express Router 中使用服务
Using Service in Express Router
我是 NodeJS 的新手,但我想学习一些新东西。我来自 .NET 奇特的依赖注入、控制反转、微服务闪亮的世界,所以我正在尝试根据我以前的经验在 TypeScript 中编写一些服务。
我正在使用 express 和 express router 创建一些 api。我在路由器中有一些方法可以处理 api 调用,我想使用某种服务对象进行数据检索和操作。
我使用构造函数注入将服务注入路由器,但如果我想使用我的服务,它会抛出一个错误:
TypeError: Cannot read property 'layoutService' of undefined
我知道这些方法是在没有上下文的情况下调用的,所以我在每个方法注册中添加了 .bind(this)
并且它有效,但我不知道这是否是最好的方法。
有没有人有更好的主意?
简化server.ts
import express, { Router } from "express";
// inversion of controll
import container from "./ioc";
import { TYPE } from "./constants";
import IMyService from "./abstract/IMyService";
// import routers
import MyRouter from "./api/MyRouter";
app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const router: Router = express.Router();
const myRouter: MyRouter = new MyRouter(container.get<IMyService>(TYPE.IMyService));
app.use("/", router);
app.use("/api/v1/layouts", layoutRouter.router);
MyRouter.ts
import IMyService from "./abstract/IMyService";
import { Router, Request, Response } from "express";
import { inject } from "inversify";
import { TYPE } from "../constants";
export default class MyRouter {
public readonly router: Router;
private readonly myService: IMyService;
constructor(
@inject(TYPE.IMyService) myService: IMyService
) {
this.myService = myService;
this.router = Router();
this.routes();
}
public GetAll(req: Request, res: Response): void {
this.myService.getAll()
.then(data => {
const status: number = res.statusCode;
res.json({ status, data });
})
.catch(err => {
const status: number = res.statusCode;
res.json({ status, err });
});
}
public GetOne(req: Request, res: Response): void {
const id: string = req.params.id;
this.myService.getOne(new ObjectID(id))
.then(data => {
const status: number = res.statusCode;
res.json({ status, data });
})
.catch(err => {
const status: number = res.statusCode;
res.json({ status, err });
});
}
routes(): void {
this.router
.get("/", this.GetAll)
.get("/:id", this.GetOne);
}
}
如果您使用箭头语法 (ES6) 定义您的函数,它会自动 "bind" 它的上下文,您不需要 bind
它们。但这取决于您的用例(您可能需要绑定不同的上下文)
我是 NodeJS 的新手,但我想学习一些新东西。我来自 .NET 奇特的依赖注入、控制反转、微服务闪亮的世界,所以我正在尝试根据我以前的经验在 TypeScript 中编写一些服务。 我正在使用 express 和 express router 创建一些 api。我在路由器中有一些方法可以处理 api 调用,我想使用某种服务对象进行数据检索和操作。 我使用构造函数注入将服务注入路由器,但如果我想使用我的服务,它会抛出一个错误:
TypeError: Cannot read property 'layoutService' of undefined
我知道这些方法是在没有上下文的情况下调用的,所以我在每个方法注册中添加了 .bind(this)
并且它有效,但我不知道这是否是最好的方法。
有没有人有更好的主意?
简化server.ts
import express, { Router } from "express";
// inversion of controll
import container from "./ioc";
import { TYPE } from "./constants";
import IMyService from "./abstract/IMyService";
// import routers
import MyRouter from "./api/MyRouter";
app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const router: Router = express.Router();
const myRouter: MyRouter = new MyRouter(container.get<IMyService>(TYPE.IMyService));
app.use("/", router);
app.use("/api/v1/layouts", layoutRouter.router);
MyRouter.ts
import IMyService from "./abstract/IMyService";
import { Router, Request, Response } from "express";
import { inject } from "inversify";
import { TYPE } from "../constants";
export default class MyRouter {
public readonly router: Router;
private readonly myService: IMyService;
constructor(
@inject(TYPE.IMyService) myService: IMyService
) {
this.myService = myService;
this.router = Router();
this.routes();
}
public GetAll(req: Request, res: Response): void {
this.myService.getAll()
.then(data => {
const status: number = res.statusCode;
res.json({ status, data });
})
.catch(err => {
const status: number = res.statusCode;
res.json({ status, err });
});
}
public GetOne(req: Request, res: Response): void {
const id: string = req.params.id;
this.myService.getOne(new ObjectID(id))
.then(data => {
const status: number = res.statusCode;
res.json({ status, data });
})
.catch(err => {
const status: number = res.statusCode;
res.json({ status, err });
});
}
routes(): void {
this.router
.get("/", this.GetAll)
.get("/:id", this.GetOne);
}
}
如果您使用箭头语法 (ES6) 定义您的函数,它会自动 "bind" 它的上下文,您不需要 bind
它们。但这取决于您的用例(您可能需要绑定不同的上下文)