-
Notifications
You must be signed in to change notification settings - Fork 402
Description
Ref. #202 (comment)
Introduction
Right now, RoutingControllersOptions
has following signatures for controllers/interceptors/middlewares -
Function[] | string[]
- which allows to register in the framework list of classes or directories from where to import
.
The array syntax is great because it let's you define the order of middlewares explicitly:
createExpressServer({
middlewares: [
MorganMiddleware,
JwtMiddleware,
AuthMiddleware,
CompressionMiddleware,
LoggingMiddleware,
ErrorMiddleware,
],
});
So there's no need to jump through middlewares files and looking for priority
option.
However, in big apps it might be not comfortable to list all of 58 controllers explicitly in array, so we have support for glob string and loading from directories:
createExpressServer({
controllers: [__dirname + "/controllers/**/*.js"],
})
The cons are that you can't disable one middleware for dev/debug purpose and you have to use priority
option in middleware decorator to declare the order of calling them which is very hard in maintaining.
In TypeScript and ES6 we can export and import from modules, so it's a common case to have index files. The directory structure looks like this:
middlewares
- auth-middleware.ts
- index.ts
- jwt-middleware.ts
- logging-middleware.ts
// etc.
And the index.ts file looks like this:
export * from "./jwt-middleware";
export * from "./auth-middleware";
export * from "./logging-middleware";
And in app.ts:
import * as middlewares from "./middlewares";
Because all object properties are traversed "in the order in which they were added to the object", we can use index.ts to manipulate the explicit order of middlewares. It doesn't have to be placed as index file, it might be placed in app configuration folder with modified paths.
Main proposal
Right now we can't pass object to routing-controllers option. So we need dirty hacks like:
createExpressServer(
middlewares: Object.keys(middlewares).map(key => (<any>middlewares)[key]),
});
I propose to add support for objects containing middlewares/controllers/interceptors. We could then just do:
import * as middlewares from "./middlewares";
createExpressServer(
middlewares: middlewares,
});
or with ES6 shorthand syntax:
import * as middlewares from "./middlewares";
import * as controllers from "./controllers";
import * as interceptors from "./interceptors";
createExpressServer({
middlewares,
controllers,
interceptors,
});
Also I think that importing all from directories by glob string is an antipattern and this proposal reduce a lot of boilerplate of explicit array option. If users get used to this feature I would even deprecate loading from directories feature.
Adding @NoNameProvided @pleerock for discussion.