깜놀하는 해므찌로

nestjs search 검색 controller service 기본 구조 예시 feat.Prisma 본문

IT

nestjs search 검색 controller service 기본 구조 예시 feat.Prisma

agnusdei1207 2023. 8. 16. 12:25
반응형
SMALL
export type PageInfo = {
  itemsCount: number;
  totalItems: number;
  itemsPerPage: number;
  totalPages: number;
  currentPage: number;
};


export class PaginationDTO<T> implements IPaginationDTO<T> {
  items: T[];
  pageInfo: PageInfo;
}

export class PaginationOptionDTO implements IPaginationOptionDTO {
  @ApiProperty()
  @IsNotEmpty()
  @Type(() => Number)
  pageNo: number;
  @ApiProperty()
  @IsNotEmpty()
  @Type(() => Number)
  pageSize: number;
  @ApiProperty()
  @IsNotEmpty()
  orderBy: string;
  @ApiProperty()
  @IsNotEmpty()
  align: 'asc' | 'desc';
  @ApiProperty()
  @IsOptional()
  query?: string;
}

1. type, interface 

 

 

export class PaginationDTO<T> implements IPaginationDTO<T> {
  items: T[];
  pageInfo: PageInfo;
}

export class PaginationOptionDTO implements IPaginationOptionDTO {
  @ApiProperty()
  @IsNotEmpty()
  @Type(() => Number)
  pageNo: number;
  @ApiProperty()
  @IsNotEmpty()
  @Type(() => Number)
  pageSize: number;
  @ApiProperty()
  @IsNotEmpty()
  orderBy: string;
  @ApiProperty()
  @IsNotEmpty()
  align: 'asc' | 'desc';
  @ApiProperty()
  @IsOptional()
  query?: string;
}

export const generatePageInfo = (
  count: number,
  itemLength: number,
  pageSize: number,
  pageNo: number
): PageInfo => ({
  currentPage: pageNo,
  itemsCount: itemLength,
  itemsPerPage: pageSize,
  totalItems: count,
  totalPages: Math.ceil(count / pageSize),
});

2. DTO <T> 제네릭을 받아 해당 타입의 배열로 프로퍼티 설정

 

 

 

@ApiTags('관리자')
@Controller({ version: '1' })
export class AdminController {
  constructor(private readonly adminService: AdminService) {}

    @Get('search')
      @ApiOperation({
        summary: '관리자 조회',
        description: '검색어와 일치하는 관리자 목록을 조회합니다.',
      })
      async searchAdmins(@Query() option: PaginationOptionDTO) {
        const [entities, count] = await this.adminService.search(option);
        const result: PaginationDTO<AdminDTO> = {
          items: plainToInstance(AdminDTO, entities),
          pageInfo: generatePageInfo(
            count,
            entities.length,
            option.pageSize,
            option.pageNo
          ),
        };
        return result;
      }

3. controller: search 검색 요청 받는 부분 (PaginationDTO<T>) 제네릭 활용

 

 

 

async search(option: PaginationOptionDTO): Promise<[Admin[], number]> {
    const where: Prisma.AdminWhereInput = {
      username: {
        contains: option.query,
      },
    };

    const orderBy: Prisma.AdminOrderByWithRelationInput = {};
    orderBy[option.orderBy] = option.align;

    const count = await this.prismaService.admin.count({ where });
    const entities = await this.prismaService.admin.findMany({
      where: { ...where },
      orderBy,
      take: option.pageSize, // items per Page
      skip: (option.pageNo - 1) * option.pageSize,
    });

    return [entities, count];
  }

4. service: prisma 에 접근해 데이터 조회

 

 

반응형
LIST