Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/iamolegga/create-nestjs-middleware-module
NestJS configured middleware module made simple
https://github.com/iamolegga/create-nestjs-middleware-module
middleware nest nestjs
Last synced: 1 day ago
JSON representation
NestJS configured middleware module made simple
- Host: GitHub
- URL: https://github.com/iamolegga/create-nestjs-middleware-module
- Owner: iamolegga
- License: mit
- Created: 2019-10-28T15:21:23.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2025-01-27T02:59:15.000Z (2 days ago)
- Last Synced: 2025-01-27T03:25:51.537Z (2 days ago)
- Topics: middleware, nest, nestjs
- Language: TypeScript
- Homepage:
- Size: 3.27 MB
- Stars: 41
- Watchers: 3
- Forks: 3
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
create-nestjs-middleware-module
NestJS configured middleware module made simple
## What is it?
It is a tiny helper library that helps you create simple _idiomatic_ **NestJS** module based on `Express`/`Fastify` middleware in just a few lines of code with routing out of the box.
## Install
```sh
npm i create-nestjs-middleware-module
```or
```sh
yarn add create-nestjs-middleware-module
```## Usage
Let's imaging you have some middleware factory, for example, simple logger:
```ts
export interface Options {
maxDuration: number
}export function createResponseDurationLoggerMiddleware(opts: Options) {
return (request, response, next) => {
const start = Date.now();response.on('finish', () => {
const message = `${request.method} ${request.path} - ${duration}ms`;const duration = Date.now() - start;
if (duration > maxDuration) {
console.warn(message);
} else {
console.log(message);
}
});next();
};
}
```And you want to create an idiomatic NestJS module based on that middleware. Just pass this middleware factory to `createModule` function:
```ts
import { createModule } from 'create-nestjs-middleware-module';
import { Options, createResponseDurationLoggerMiddleware } from './middleware';export const TimingModule = createModule(createResponseDurationLoggerMiddleware);
```That's it, your module is ready. Let's see what API it has:
```ts
import { TimingModule } from './timing-module';
import { MyController } from './my.controller';@Module({
imports: [// 1. `.forRoot()` method accept params satisfying `Options` interface
TimingModule.forRoot({ maxDuration: 1000 }),// 2. `.forRoot()` method accept additional optional routing params
TimingModule.forRoot({
maxDuration: 1000,// both `forRoutes` and `exclude` properties are optional
// and has the same API as NestJS buil-in `MiddlewareConfigProxy`
// @see https://docs.nestjs.com/middleware#applying-middleware
forRoutes: [MyController],
exclude: [{ method: RequestMethod.ALL, path: 'always-fast' }],
}),// 3. `.forRootAsync()` method with only factory
TimingModule.forRootAsync({
useFactory: async () => {
return { maxDuration: 1000 }
}
}),// 4. `.forRootAsync()` method with dependencies
TimingModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: async (config: ConfigService) => {
return { maxDuration: config.maxDurationForAPIHandler }
}
}),// 5. `.forRootAsync()` method with routing
TimingModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: async (config: ConfigService) => {
return {
maxDuration: config.maxDurationForAPIHandler// both `forRoutes` and `exclude` properties are optional
// and has the same API as NestJS buil-in `MiddlewareConfigProxy`
// @see https://docs.nestjs.com/middleware#applying-middleware
forRoutes: [MyController],
exclude: [{ method: RequestMethod.ALL, path: 'always-fast' }],
};
}
}),
]
controllers: [MyController /*, ... */]
})
class App {}
```## More examples
See examples of usage in `__tests__` folder or [nestjs-session](https://github.com/iamolegga/nestjs-session/blob/master/src/index.ts) and [nestjs-cookie-session](https://github.com/iamolegga/nestjs-cookie-session/blob/master/src/index.ts) packages
## Notes
1. `createModule` callback function can return not only one middleware, but array of it.
```ts
import { createModule } from 'create-nestjs-middleware-module';interface Options {
// ...
}createModule((options) => {
function firstMidlleware() { /* ... */ }
function secondMidlleware() { /* ... */ }
return [firstMidlleware, secondMidlleware]
});
```2. If your `Options` interface has not __required__ properties it can be frustrating to force end-users of your module to call `forRoot({})`, and for better developer expirience you can cast `createModule(...)` result to `FacadeModuleStaticOptional`, then `forRoot()` could be called without arguments and without TS error. In such case `createModule` callback function will be called with empty object `{}`.
```ts
import { createModule, FacadeModuleStaticOptional } from 'create-nestjs-middleware-module';interface Options {
maxDuration?: number;
}createModule((options) => {
typeof options // always "object" even if not passed to `forRoot()`return (request, response, next) => {
// ...
next();
};
}) as FacadeModuleStaticOptional;
```3. For better developer experience of end-users of your module you can also export interfaces of `forRoot` and `forRootAsync` argument:
```ts
import {
AsyncOptions,
SyncOptions,
} from 'create-nestjs-middleware-module';interface Options {
// ...
}export type MyModuleOptions = SyncOptions;
export type MyModuleAsyncOptions = AsyncOptions;
```4. This library is tested against `express` and `fastify`. But you should be aware that middlewares of `express` are not always work with `fastify` and vise versa. Sometimes you can check platforms internally. Sometimes maybe it's better to create 2 separate modules for each platform. It's up to you.
Do you use this library?
Don't be shy to give it a star! ★Also if you are into NestJS you might be interested in one of my other NestJS libs.