Skip to content

Instantly share code, notes, and snippets.

@alexbridge
Last active November 4, 2023 08:13
Show Gist options
  • Save alexbridge/e1efaf29611072b6b585c22aaa554e37 to your computer and use it in GitHub Desktop.
Save alexbridge/e1efaf29611072b6b585c22aaa554e37 to your computer and use it in GitHub Desktop.
Nestjs Entity param converter. Convert request parameter to domain entity

Nestjs Entity param converter pipe

Convert input param into domain entity.

@Controller('books')
export class BooksController {
  @Get('/:id')
  async getBook(@Param('id', IdToEntityPipe()) book: BookEntity): Promise<BookEntity> {
    return book;
  }
}

Inspired by:

import { Controller, Get, Param } from '@nestjs/common';
import { IdToEntityPipe } from 'id-to-entity.pipe';
type BookEntity = {
id: number;
name: string;
};
@Controller('books')
export class BooksController {
@Get('/:id')
async getBook(@Param('id', IdToEntityPipe()) book: BookEntity): Promise<BookEntity> {
return book;
}
}
import { ArgumentMetadata, Injectable, Logger, NotFoundException, PipeTransform } from '@nestjs/common';
import { InjectEntityManager } from '@nestjs/typeorm';
import { EntityManager } from 'typeorm';
export const IdToEntityPipe = (property: string = 'id') => {
@Injectable()
class IdToEntityPipe implements PipeTransform {
readonly logger = new Logger(IdToEntityPipe.name);
constructor(@InjectEntityManager() readonly entityManager: EntityManager) {}
async transform(value: string, metadata: ArgumentMetadata): Promise<any> {
const { metatype } = metadata;
const entity = await this.entityManager.findOne(metatype, {
where: { [property]: value },
});
if (!entity) {
this.logger.log(`Entity not found: ${metatype} with ${property}:${value}`);
throw new NotFoundException(`${metatype} with ${property}:${value} not found`);
}
this.logger.log(`Entity found ${metatype} with ${property}:${value} -> ${entity}`);
return entity;
}
}
return IdToEntityPipe;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment