Skip to content

Commit 3107a46

Browse files
authored
Merge pull request #252 from 19majkel94/fix/middlewares-loading-order
Fix/middlewares loading order
2 parents ed63979 + fde2ac6 commit 3107a46

File tree

4 files changed

+168
-6
lines changed

4 files changed

+168
-6
lines changed

src/RoutingControllers.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,7 @@ export class RoutingControllers {
9595
this.metadataBuilder
9696
.buildMiddlewareMetadata(classes)
9797
.filter(middleware => middleware.global && middleware.type === type)
98-
.sort((middleware1, middleware2) => middleware1.priority - middleware2.priority)
99-
.reverse()
98+
.sort((middleware1, middleware2) => middleware2.priority - middleware1.priority)
10099
.forEach(middleware => this.driver.registerMiddleware(middleware));
101100

102101
return this;

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ export function createExecutor(driver: Driver, options: RoutingControllersOption
215215
new RoutingControllers(driver, options)
216216
.initialize()
217217
.registerInterceptors(interceptorClasses)
218-
.registerMiddlewares("before")
218+
.registerMiddlewares("before", middlewareClasses)
219219
.registerControllers(controllerClasses)
220220
.registerMiddlewares("after", middlewareClasses); // todo: register only for loaded controllers?
221221
}

src/metadata-builder/MetadataArgsStorage.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ export class MetadataArgsStorage {
6464
* Filters registered middlewares by a given classes.
6565
*/
6666
filterMiddlewareMetadatasForClasses(classes: Function[]): MiddlewareMetadataArgs[] {
67-
return this.middlewares.filter(ctrl => {
68-
return classes.filter(cls => ctrl.target === cls).length > 0;
69-
});
67+
return classes
68+
.map(cls => this.middlewares.find(mid => mid.target === cls))
69+
.filter(midd => midd !== undefined); // this might be not needed if all classes where decorated with `@Middleware`
7070
}
7171

7272
/**
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
import "reflect-metadata";
2+
import {createExpressServer, getMetadataArgsStorage} from "../../src/index";
3+
import {ExpressMiddlewareInterface} from "../../src/driver/express/ExpressMiddlewareInterface";
4+
import {Controller} from "../../src/decorator/Controller";
5+
import {Get} from "../../src/decorator/Get";
6+
import {UseBefore} from "../../src/decorator/UseBefore";
7+
import {Middleware} from "../../src/decorator/Middleware";
8+
import {UseAfter} from "../../src/decorator/UseAfter";
9+
import {NotAcceptableError} from "./../../src/http-error/NotAcceptableError";
10+
import {ExpressErrorMiddlewareInterface} from "./../../src/driver/express/ExpressErrorMiddlewareInterface";
11+
const chakram = require("chakram");
12+
const expect = chakram.expect;
13+
14+
describe("order of middlewares", () => {
15+
16+
describe("loaded direct from array", () => {
17+
18+
let middlewaresOrder: number[];
19+
20+
beforeEach(() => {
21+
middlewaresOrder = [];
22+
});
23+
24+
let app: any;
25+
before(done => {
26+
27+
// reset metadata args storage
28+
getMetadataArgsStorage().reset();
29+
30+
@Middleware({ type: "after" })
31+
class ThirdAfterMiddleware implements ExpressMiddlewareInterface {
32+
33+
use(request: any, response: any, next: (err?: any) => any) {
34+
middlewaresOrder.push(3);
35+
next();
36+
}
37+
38+
}
39+
40+
@Middleware({ type: "after" })
41+
class FirstAfterMiddleware implements ExpressMiddlewareInterface {
42+
43+
use(request: any, response: any, next: (err?: any) => any) {
44+
middlewaresOrder.push(1);
45+
next();
46+
}
47+
48+
}
49+
50+
@Middleware({ type: "after" })
51+
class SecondAfterMiddleware implements ExpressMiddlewareInterface {
52+
53+
use(request: any, response: any, next: (err?: any) => any) {
54+
middlewaresOrder.push(2);
55+
next();
56+
}
57+
58+
}
59+
60+
@Controller()
61+
class ExpressMiddlewareController {
62+
63+
@Get("/test")
64+
test() {
65+
return "OK";
66+
}
67+
68+
}
69+
70+
app = createExpressServer({
71+
middlewares: [FirstAfterMiddleware, SecondAfterMiddleware, ThirdAfterMiddleware]
72+
}).listen(3001, done);
73+
});
74+
75+
after(done => app.close(done));
76+
77+
it("should call middlewares in order defined by items order", () => {
78+
return chakram
79+
.get("http://127.0.0.1:3001/test")
80+
.then((response: any) => {
81+
expect(response).to.have.status(200);
82+
expect(middlewaresOrder[0]).to.equal(1);
83+
expect(middlewaresOrder[1]).to.equal(2);
84+
expect(middlewaresOrder[2]).to.equal(3);
85+
});
86+
});
87+
88+
});
89+
90+
describe("specified by priority option", () => {
91+
92+
let middlewaresOrder: number[];
93+
94+
beforeEach(() => {
95+
middlewaresOrder = [];
96+
});
97+
98+
let app: any;
99+
before(done => {
100+
101+
// reset metadata args storage
102+
getMetadataArgsStorage().reset();
103+
104+
@Middleware({ type: "after", priority: 0 })
105+
class ThirdAfterMiddleware implements ExpressMiddlewareInterface {
106+
107+
use(request: any, response: any, next: (err?: any) => any) {
108+
middlewaresOrder.push(3);
109+
next();
110+
}
111+
112+
}
113+
114+
@Middleware({ type: "after", priority: 8 })
115+
class FirstAfterMiddleware implements ExpressMiddlewareInterface {
116+
117+
use(request: any, response: any, next: (err?: any) => any) {
118+
middlewaresOrder.push(1);
119+
next();
120+
}
121+
122+
}
123+
124+
@Middleware({ type: "after", priority: 4 })
125+
class SecondAfterMiddleware implements ExpressMiddlewareInterface {
126+
127+
use(request: any, response: any, next: (err?: any) => any) {
128+
middlewaresOrder.push(2);
129+
next();
130+
}
131+
132+
}
133+
134+
@Controller()
135+
class ExpressMiddlewareController {
136+
137+
@Get("/test")
138+
test() {
139+
return "OK";
140+
}
141+
142+
}
143+
144+
app = createExpressServer({
145+
middlewares: [SecondAfterMiddleware, ThirdAfterMiddleware, FirstAfterMiddleware]
146+
}).listen(3001, done);
147+
});
148+
149+
after(done => app.close(done));
150+
151+
it("should call middlewares in order defined by priority parameter of decorator", () => {
152+
return chakram
153+
.get("http://127.0.0.1:3001/test")
154+
.then((response: any) => {
155+
expect(response).to.have.status(200);
156+
expect(middlewaresOrder[0]).to.equal(1);
157+
expect(middlewaresOrder[1]).to.equal(2);
158+
expect(middlewaresOrder[2]).to.equal(3);
159+
});
160+
});
161+
});
162+
163+
});

0 commit comments

Comments
 (0)