问题
I followed the documentation and was able to add an interceptor for response mapping.
I want a consistent json format output for responses.
How can I achieve this with interceptor or with something else better than this approach.
{
"statusCode": 201,
"message": "Custom Dynamic Message"
"data": {
// properties
meta: {}
}
}
transform.interceptor.ts
import {
Injectable,
NestInterceptor,
ExecutionContext,
CallHandler,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
export interface Response<T> {
statusCode: number;
data: T;
}
@Injectable()
export class TransformInterceptor<T>
implements NestInterceptor<T, Response<T>> {
intercept(
context: ExecutionContext,
next: CallHandler,
): Observable<Response<T>> {
return next
.handle()
.pipe(
map((data) => ({
statusCode: context.switchToHttp().getResponse().statusCode,
data,
})),
);
}
}
app.controller.ts
export class AppController {
@Post('login')
@UseGuards(AuthGuard('local'))
@ApiOperation({ summary: 'Login user' })
@ApiBody({ type: LoginDto })
@ApiOkResponse({ content: { 'application/json': {} } })
@UseInterceptors(TransformInterceptor)
async login(@Request() req) {
const result = await this.authService.login(req.user);
return { message: 'Thank you!', result };
}
}
回答1:
If I am understanding what you are doing with your controller response and your overall interceptor response, what you can do is something similar:
import {
Injectable,
NestInterceptor,
ExecutionContext,
CallHandler,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
export interface Response<T> {
statusCode: number;
message: string;
data: T;
}
@Injectable()
export class TransformInterceptor<T>
implements NestInterceptor<T, Response<T>> {
intercept(
context: ExecutionContext,
next: CallHandler,
): Observable<Response<T>> {
return next
.handle()
.pipe(
map((data) => ({
statusCode: context.switchToHttp().getResponse().statusCode,
message: data.message
data: {
result: data.result,
meta: {} // if this is supposed to be the actual return then replace {} with data.result
}
})),
);
}
}
And keep your controller return as {message: 'Custom message', result}
.
Another option, which would require more upfront but possible allow for cleaner code would be to create a custom decorator that reflected a value (message) from the class and method and then retrieved that value in the interceptor after injecting the reflector, but again, that would take more upfront effort to set up.
来源:https://stackoverflow.com/questions/60189849/how-to-format-response-before-sending-in-nest-js