expressjs 反转控制器中间件错误
expressjs inversify controller middleware error
我正在使用 nodejs、express 和 inversify 构建一个非常小的休息 api。
这是我的工作代码:
index.ts
const container = new Container();
container.bind<interfaces.Controller>(Types.Controller)
.to(MyController)
.whenTargetNamed(Targets.Controller.MyController);
container.bind<Types.Service>(Types.Service)
.to(MyService)
.whenTargetNamed(Targets.Services.MyService);
const server = new InversifyExpressServer(container);
const app = server.build();
app.listen(3000);
mycontroller.ts
@injectable()
@controller('/api/test')
export class MyController {
constructor(@inject(Types.Service)
@named(Targets.Service.MyService)
private MyService: MyService) { }
@httpGet('/')
public getCompanies(req: Request, res: Response, next: any): Promise<any[]>
{
console.log('getTestData');
return this.MyService.fetchAll();
}
}
以上代码运行良好。
当我想使用中间件来检查授权令牌时,问题就出现了。
authmiddleware.ts
function authMiddlewareFactory(
{
return (config: { role: string }) =>
{
return (req: Request, res: Response, next: any): void =>
{
const token = getToken(req);
console.log(token);
if (token === null)
{
res.status(403).json({ err: 'You are not allowed' });
return;
}
next();
}
}
const authMiddleware = authMiddlewareFactory();
export { authMiddleware };
如果我直接在控制器中直接使用 auth 中间件,我会按预期收到 'You are not allowed' 消息:
mycontroller.ts
@httpGet('/')
public getCompanies(req: Request, res: Response, next: any): Promise<any[]>
{
authMiddleware({ role: "admin" })(req, res, next);
console.log('getCompanies');
return this.CompanyService.fetchAll();
}
但是如果我使用反转:
import { authMiddleware } from './authmiddleware'
@injectable()
@controller('/api/test', authMiddleware({ role: "admin" }))
export class MyController {
// same code as before
编译时出现如下错误:
ERROR: No matching bindings found for serviceIdentifier:
Error: No matching bindings found for serviceIdentifier:
at InversifyExpressServer.resolveMidleware (node_modules/inversify-express-utils/lib/server.js:133:27)
at InversifyExpressServer.registerControllers (inversify-express-utils/lib/server.js:106:21)
at InversifyExpressServer.build (node_modules/inversify-express-utils/lib/server.js:94:14)
at Object. (dist/index.js:52:20)
我假设我必须在 index.ts 中声明我的中间件,就像我为控制器和服务所做的那样。我尝试了但没有成功。
谢谢
我使用的是以下版本:
"inversify": "4.5.2",
"inversify-express-utils": "5.0.0",
"reflect-metadata": "0.1.10",
"chai": "4.0.2",
"@types/chai": "4.0.0",
"@types/supertest": "2.0.2 ",
"supertest": "3.0.0",
我写了以下快速测试:
import "reflect-metadata";
import * as express from "express";
import { expect } from "chai";
import { Container, injectable, inject, named } from "inversify";
import { InversifyExpressServer, interfaces, controller, httpGet } from "inversify-express-utils";
import * as request from "supertest";
interface IMyService {
fetchAll(): Promise<string[]>;
}
const Types = {
Service: Symbol.for("Service")
};
const Targets = {
Service: {
MyService: "MyService"
}
};
function authMiddlewareFactory() {
return (config: { role: string }) => {
return (req: express.Request, res: express.Response, next: express.NextFunction): void => {
const token = req.headers["x-auth-token"];
console.log(token);
if (token === null) {
res.status(403).json({ err: "You are not allowed" });
return;
}
next();
};
};
}
const authMiddleware = authMiddlewareFactory();
const container = new Container();
@injectable()
class MyService implements IMyService {
public fetchAll() {
return Promise.resolve(["Hello", "World"]);
}
}
@controller("/api/test")
export class MyController {
constructor(
@inject(Types.Service) @named(Targets.Service.MyService) private myService: MyService
) { }
@httpGet("/", authMiddleware({ role: "admin" }))
public async getCompanies(req: express.Request, res: express.Response, next: express.NextFunction): Promise<string[]> {
console.log("getTestData");
return await this.myService.fetchAll();
}
}
container.bind<MyService>(Types.Service)
.to(MyService)
.whenTargetNamed(Targets.Service.MyService);
const server = new InversifyExpressServer(container);
const app = server.build();
request(app)
.get("/api/test")
.set("x-auth-token", "Token 1234567890")
.expect("Content-Type", /json/)
.expect(200)
.expect(function(res: any) {
const b = res.body;
console.log(b);
expect(b[0]).eq("Hello");
expect(b[1]).eq("World");
})
.end(function(err, res) {
if (err) {
throw err;
}
});
它打印以下内容:
Token 1234567890
getTestData
[ 'Hello', 'World' ]
在inversify-express-utils
5.0.0(目前推荐的版本)中,您不需要为控制器声明绑定,也不需要用@injectable()
装饰控制器。
我使用一个唯一文件创建示例,但在实际应用程序中,您将有多个文件。您需要导入您的控制器一次:
import "./controllers/some_controller";
您可以在 https://github.com/inversify/inversify-express-utils#important-information-about-the-controller-decorator and https://github.com/inversify/inversify-express-utils/releases/tag/5.0.0 了解更多信息。
我正在使用 nodejs、express 和 inversify 构建一个非常小的休息 api。
这是我的工作代码:
index.ts
const container = new Container();
container.bind<interfaces.Controller>(Types.Controller)
.to(MyController)
.whenTargetNamed(Targets.Controller.MyController);
container.bind<Types.Service>(Types.Service)
.to(MyService)
.whenTargetNamed(Targets.Services.MyService);
const server = new InversifyExpressServer(container);
const app = server.build();
app.listen(3000);
mycontroller.ts
@injectable()
@controller('/api/test')
export class MyController {
constructor(@inject(Types.Service)
@named(Targets.Service.MyService)
private MyService: MyService) { }
@httpGet('/')
public getCompanies(req: Request, res: Response, next: any): Promise<any[]>
{
console.log('getTestData');
return this.MyService.fetchAll();
}
}
以上代码运行良好。 当我想使用中间件来检查授权令牌时,问题就出现了。
authmiddleware.ts
function authMiddlewareFactory(
{
return (config: { role: string }) =>
{
return (req: Request, res: Response, next: any): void =>
{
const token = getToken(req);
console.log(token);
if (token === null)
{
res.status(403).json({ err: 'You are not allowed' });
return;
}
next();
}
}
const authMiddleware = authMiddlewareFactory();
export { authMiddleware };
如果我直接在控制器中直接使用 auth 中间件,我会按预期收到 'You are not allowed' 消息:
mycontroller.ts
@httpGet('/')
public getCompanies(req: Request, res: Response, next: any): Promise<any[]>
{
authMiddleware({ role: "admin" })(req, res, next);
console.log('getCompanies');
return this.CompanyService.fetchAll();
}
但是如果我使用反转:
import { authMiddleware } from './authmiddleware'
@injectable()
@controller('/api/test', authMiddleware({ role: "admin" }))
export class MyController {
// same code as before
编译时出现如下错误:
ERROR: No matching bindings found for serviceIdentifier:
Error: No matching bindings found for serviceIdentifier:
at InversifyExpressServer.resolveMidleware (node_modules/inversify-express-utils/lib/server.js:133:27) at InversifyExpressServer.registerControllers (inversify-express-utils/lib/server.js:106:21) at InversifyExpressServer.build (node_modules/inversify-express-utils/lib/server.js:94:14) at Object. (dist/index.js:52:20)
我假设我必须在 index.ts 中声明我的中间件,就像我为控制器和服务所做的那样。我尝试了但没有成功。
谢谢
我使用的是以下版本:
"inversify": "4.5.2",
"inversify-express-utils": "5.0.0",
"reflect-metadata": "0.1.10",
"chai": "4.0.2",
"@types/chai": "4.0.0",
"@types/supertest": "2.0.2 ",
"supertest": "3.0.0",
我写了以下快速测试:
import "reflect-metadata";
import * as express from "express";
import { expect } from "chai";
import { Container, injectable, inject, named } from "inversify";
import { InversifyExpressServer, interfaces, controller, httpGet } from "inversify-express-utils";
import * as request from "supertest";
interface IMyService {
fetchAll(): Promise<string[]>;
}
const Types = {
Service: Symbol.for("Service")
};
const Targets = {
Service: {
MyService: "MyService"
}
};
function authMiddlewareFactory() {
return (config: { role: string }) => {
return (req: express.Request, res: express.Response, next: express.NextFunction): void => {
const token = req.headers["x-auth-token"];
console.log(token);
if (token === null) {
res.status(403).json({ err: "You are not allowed" });
return;
}
next();
};
};
}
const authMiddleware = authMiddlewareFactory();
const container = new Container();
@injectable()
class MyService implements IMyService {
public fetchAll() {
return Promise.resolve(["Hello", "World"]);
}
}
@controller("/api/test")
export class MyController {
constructor(
@inject(Types.Service) @named(Targets.Service.MyService) private myService: MyService
) { }
@httpGet("/", authMiddleware({ role: "admin" }))
public async getCompanies(req: express.Request, res: express.Response, next: express.NextFunction): Promise<string[]> {
console.log("getTestData");
return await this.myService.fetchAll();
}
}
container.bind<MyService>(Types.Service)
.to(MyService)
.whenTargetNamed(Targets.Service.MyService);
const server = new InversifyExpressServer(container);
const app = server.build();
request(app)
.get("/api/test")
.set("x-auth-token", "Token 1234567890")
.expect("Content-Type", /json/)
.expect(200)
.expect(function(res: any) {
const b = res.body;
console.log(b);
expect(b[0]).eq("Hello");
expect(b[1]).eq("World");
})
.end(function(err, res) {
if (err) {
throw err;
}
});
它打印以下内容:
Token 1234567890
getTestData
[ 'Hello', 'World' ]
在inversify-express-utils
5.0.0(目前推荐的版本)中,您不需要为控制器声明绑定,也不需要用@injectable()
装饰控制器。
我使用一个唯一文件创建示例,但在实际应用程序中,您将有多个文件。您需要导入您的控制器一次:
import "./controllers/some_controller";
您可以在 https://github.com/inversify/inversify-express-utils#important-information-about-the-controller-decorator and https://github.com/inversify/inversify-express-utils/releases/tag/5.0.0 了解更多信息。