How to exclude entity field from returned by controller JSON. NestJS + Typeorm How to exclude entity field from returned by controller JSON. NestJS + Typeorm typescript typescript

How to exclude entity field from returned by controller JSON. NestJS + Typeorm


I'd suggest creating an interceptor that takes advantage of the class-transformer library:

@Injectable()export class TransformInterceptor implements NestInterceptor {  intercept(    context: ExecutionContext,    call$: Observable<any>,  ): Observable<any> {    return call$.pipe(map(data => classToPlain(data)));  }}

Then, simply exclude properties using @Exclude() decorator, for example:

import { Exclude } from 'class-transformer';export class User {    id: number;    email: string;    @Exclude()    password: string;}


You can overwrite the toJSON method of the model like this.

@Entity()export class User extends BaseAbstractEntity implements IUser {  static passwordMinLength: number = 7;  @ApiModelProperty({ example: faker.internet.email() })  @IsEmail()  @Column({ unique: true })  email: string;  @IsOptional()  @IsString()  @MinLength(User.passwordMinLength)  @Exclude({ toPlainOnly: true })  @Column({ select: false })  password: string;  @IsOptional()  @IsString()  @Exclude({ toPlainOnly: true })  @Column({ select: false })  passwordSalt: string;  toJSON() {    return classToPlain(this);  }  validatePassword(password: string) {    if (!this.password || !this.passwordSalt) {      return false;    }    return comparedToHashed(password, this.password, this.passwordSalt);  }}

By using the class-transformer method of plainToClass along with the @Exclude({ toPlainOnly: true }), the password will be excluded from the JSON response, but will be available in the model instance. I like this solution because it keeps all the model configuration in the entity.


As an addition to Kamil's answer:

Instead of creating your own interceptor, you can now use the built-in ClassSerializerInterceptor, see the serialization docs.

@UseInterceptors(ClassSerializerInterceptor)

You can use it on a controller class or its individual methods. Each entity returned by such a method will be transformed with class-transformer and hence take the @Exclude annotations into account:

import { Exclude } from 'class-transformer';export class User {    /** other properties */        @Exclude()    password: string;}

You can customize its behavior by defining @SerializeOptions() on your controller or its methods:

@SerializeOptions({  excludePrefixes: ['_'],  groups: ['admin']})

to, for example, expose certain fields only to certain users:

@Expose({ groups: ["admin"] })adminInfo: string;