Reputation: 484
I want to increase request body size limit for a single route, let's say only for route /uploads
, and keep the rest to be the default.
I know you can set globally using
app.use(json({ limit: '50mb' }));
Or, when in pure ExpressJS you can use
router.use('/uploads', express.json({ limit: '50MB' }));
But in NestJS there's only a global app
and controller classes. E.g.
@Controller('uploads')
export class UploadController {
constructor() {}
@Post()
create(...): Promise<any> {
...
}
}
Where to set the limit for this controller?
Upvotes: 4
Views: 14846
Reputation: 915
Instead of setting the size limit per route in main.ts, you can set a high limit for all routes and then use an interceptor to set a limit per controller. And the client will get a more descriptive error when exceeding the limit.
import { Injectable, NestInterceptor, ExecutionContext, CallHandler, HttpException } from '@nestjs/common';
import { Observable } from 'rxjs';
@Injectable()
export class SizeLimitInterceptor implements NestInterceptor {
private sizeLimit = 0;
constructor(sizeLimit: number) {
this.sizeLimit = sizeLimit;
}
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const ctx = context.switchToHttp();
const request = ctx.getRequest();
const response = ctx.getResponse();
const size = request.socket.bytesRead;
if (size > this.sizeLimit) {
throw new HttpException('Request Entity Too Large Error', 413);
}
return next.handle();
}
}
And you can use this interceptor like this in your controller:
@UseInterceptors(new SizeLimitInterceptor(1024 * 1024 * 10))
Upvotes: 2
Reputation: 915
Actually, it is possible to increase the size limit for one route in NestJS, like this:
app.use('/uploads', json({ limit: '50mb' }));
app.use(json({ limit: '100kb' }));
Second statement is needed for resetting the limit for all other routes.
Upvotes: 11
Reputation: 31
You can use guard for this.
import {
Injectable,
CanActivate,
ExecutionContext,
applyDecorators,
UseGuards,
SetMetadata,
} from '@nestjs/common'
import { Reflector } from '@nestjs/core'
@Injectable()
export class LimitGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const request = context.switchToHttp().getRequest()
const limit = this.reflector.get<string[]>('limit', context.getHandler())
return limit > request.socket.bytesRead
}
}
export const Limit = (limit: number) =>
applyDecorators(UseGuards(LimitGuard), SetMetadata('limit', limit))
and, in your controller
@Limit(1024 * 1024)
@Post('your-path')
async limitedMethod(): Promise<string> {
// ...
}
Upvotes: 3