# Dto Response

> Use when creating or modifying DTO files in the `dto/` folder.

- Skill: `majiayu000/dto-response` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add majiayu000/dto-response`
- Raw SKILL.md: https://api.skillmd.com/api/skills/majiayu000/dto-response/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: majiayu000 (https://skillmd.com/u/majiayu000)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/majiayu000/dto-response

---


# DTO and Response Class Guide

Use this skill when creating or modifying DTO files in the `dto/` folder.

## Input DTO (Request)

```typescript
import { IsDateString, IsEnum, IsNotEmpty, IsOptional, IsString, Length } from 'class-validator';
import { IsE164 } from 'src/app.utils';

import { EntityEnum } from '../entity.enums';

export class CreateEntityDto {
  @IsNotEmpty()
  @IsString()
  requiredField!: string;

  @IsOptional()
  @IsString()
  @Length(1, 30)
  optionalField?: string;

  @IsOptional()
  @IsDateString()
  dateField?: string;

  @IsOptional()
  @IsEnum(EntityEnum)
  enumField?: EntityEnum;
}
```

### Input DTO Rules

1. **Use class-validator decorators**
   - `@IsNotEmpty()`: Required fields
   - `@IsOptional()`: Optional fields
   - `@IsString()`, `@IsNumber()`, `@IsBoolean()`: Type validation
   - `@IsEnum()`: Enum value validation
   - `@Length()`: String length limits
   - `@IsDateString()`: ISO 8601 date strings

2. **Field Declaration**
   - Required fields: `!` (definite assignment assertion)
   - Optional fields: `?` (optional)

3. **Custom Decorators**
   - Phone numbers: `@IsE164()` (E.164 format validation)
   - Define additional decorators in `app.utils.ts` as needed

4. **Naming Conventions**
   - Find: `Find{Entity}Dto`
   - Create: `Create{Entity}Dto`
   - Update: `Update{Entity}Dto`
   - Other: `{Action}{Entity}Dto`

## Output Response Class

```typescript
import { Expose } from 'class-transformer';

import { EntityEnum } from '../entity.enums';

export class FindEntityRes {
  @Expose()
  id!: string;

  @Expose()
  name!: string;

  @Expose()
  enumField!: EntityEnum;

  @Expose()
  createdAt!: Date;
}
```

### Output Response Rules

1. **@Expose() decorator is required**
   - Use `@Expose()` on all fields to expose
   - Works with `excludeExtraneousValues: true` option

2. **Naming Conventions**
   - Find: `Find{Entity}Res`
   - Create: `Create{Entity}Res`
   - Update: `Update{Entity}Res`
   - Other: `{Action}{Entity}Res`

3. **Entity → Response Transformation**

```typescript
import { mapTo } from '../app.utils';

// Usage in controller
return mapTo(FindEntityRes, entity);
```

## DTO/Response Same File Pattern

Define in same file when DTO and Response are closely related (e.g., update API):

```typescript
// update-entity.dto.ts
import { Expose } from 'class-transformer';
import { IsOptional, IsString, Length } from 'class-validator';

export class UpdateEntityDto {
  @IsOptional()
  @IsString()
  @Length(0, 30)
  name?: string;
}

export class UpdateEntityRes {
  @Expose()
  id!: string;

  @Expose()
  name!: string;
}
```

## mapTo Utility

Transformation function defined in `app.utils.ts`:

```typescript
import { type ClassConstructor, plainToInstance } from 'class-transformer';

export function mapTo<T, I>(type: ClassConstructor<T>, instance: I): T {
  return plainToInstance(type, instance, {
    excludeExtraneousValues: true,
  });
}
```

## Custom Validator Pattern

```typescript
import { applyDecorators } from '@nestjs/common';
import { Matches } from 'class-validator';

export function IsE164(): PropertyDecorator {
  return applyDecorators(
    Matches(/^\+[1-9]\d{1,14}$/, {
      message: '전화번호는 E.164을 준수해야 합니다.',
    }),
  );
}
```

## File Structure

```
src/{module}/dto/
├── create-{entity}.dto.ts
├── update-{entity}.dto.ts
├── find-{entity}.dto.ts
└── index.ts  # barrel export
```

### index.ts (Barrel Export)

```typescript
export * from './create-entity.dto';
export * from './update-entity.dto';
export * from './find-entity.dto';
```

## ValidationPipe Configuration

Global pipe setup in `main.ts`:

```typescript
app.useGlobalPipes(
  new ValidationPipe({
    whitelist: true,           // Remove undefined fields
    forbidNonWhitelisted: true, // Error on undefined fields
    transform: true,           // Auto type transformation
  }),
);
```


