> For the complete documentation index, see [llms.txt](https://jakekwak.gitbook.io/nestjs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jakekwak.gitbook.io/nestjs/overview/custom-decorators.md).

# Custom decorators

## Custom route decorators

Nest는 **decorators**라는 언어 기능을 중심으로 구축되었습니다. 데코레이터는 일반적으로 사용되는 많은 프로그래밍 언어에서 잘 알려진 개념이지만 JavaScript 세계에서는 여전히 비교적 새로운 개념입니다. 데코레이터의 작동 방식을 더 잘 이해하려면 [이 기사](https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841)를 읽는 것이 좋습니다. 간단한 정의는 다음과 같습니다.

> &#x20;ES2016 데코레이터는 함수를 반환하고 대상, 이름 및 속성 설명자를 인수로 사용할 수있는 표현식입니다. 데코레이터 앞에 `@` 문자를 붙여 장식하려는 맨 위에 배치하여 적용합니다. 클래스 또는 속성에 대해 데코레이터를 정의 할 수 있습니다.

## Param decorators

Nest는 HTTP 라우트 핸들러와 함께 사용할 수 있는 유용한 **파라미터 데코레이터** 세트를 제공합니다. 아래는 제공된 데코레이터와 이들이 나타내는 일반 Express (또는 Fastify) 객체의 목록입니다.

| `@Request()`               | `req`                                |
| -------------------------- | ------------------------------------ |
| `@Response()`              | `res`                                |
| `@Next()`                  | `next`                               |
| `@Session()`               | `req.session`                        |
| `@Param(param?: string)`   | `req.params` / `req.params[param]`   |
| `@Body(param?: string)`    | `req.body` / `req.body[param]`       |
| `@Query(param?: string)`   | `req.query` / `req.query[param]`     |
| `@Headers(param?: string)` | `req.headers` / `req.headers[param]` |

또한 자신 만의 **사용자 정의 데코레이터**를 만들 수 있습니다. 이것이 왜 유용한가요?

node.js 세계에서는 **요청** 객체에 속성을 연결하는 것이 일반적입니다. 그런 다음 다음과 같은 코드를 사용하여 각 경로 핸들러에서 수동으로 추출하십시오.

```typescript
const user = req.user;
```

코드를 읽기 쉽고 투명하게 만들기 위해 `@User()`데코레이터를 만들어 모든 컨트롤러에서 재 사용할 수 있습니다.

```typescript
@@filename(user.decorator)
import { createParamDecorator } from '@nestjs/common';

export const User = createParamDecorator((data, req) => {
  return req.user;
});
```

Then, you can simply use it wherever it fits your requirements.

```typescript
@@filename()
@Get()
async findOne(@User() user: UserEntity) {
  console.log(user);
}
@@switch
@Get()
@Bind(User())
async findOne(user) {
  console.log(user);
}
```

## Passing data

데코레이터의 동작이 일부 조건에 의존하는 경우 `data` 매개 변수를 사용하여 데코레이터의 팩토리 함수에 인수를 전달할 수 있습니다. 이를 위한 한 가지 유스 케이스는 키로 요청 오브젝트에서 특성을 추출하는 사용자 정의 데코레이터입니다. 예를 들어  [인증 계층](https://app.gitbook.com/s/-LpOhNvIYtogx8UUAkWn/overview/techniques/authentication#user-object)이 요청의 유효성을 검사하고 사용자 개체를 요청 개체에 연결한다고 가정합니다. 인증된 요청의 사용자 엔티티는 다음과 같습니다.

```javascript
{
  "id": 101,
  "firstName": "Alan",
  "lastName": "Turing",
  "email": "alan@email.com",
  "roles": ["admin"]
}
```

속성 이름을 키로 사용하는 데코레이터를 정의하고, 존재하는 경우 (또는 존재하지 않는 경우 또는 `사용자`개체가 생성되지 않은 경우에는 정의되지 않은) 연관된 값을 반환합니다.

```typescript
@@filename(user.decorator)
import { createParamDecorator } from '@nestjs/common';

export const User = createParamDecorator((data: string, req) => {
  return data ? req.user && req.user[data] : req.user;
});
@@switch
import { createParamDecorator } from '@nestjs/common';

export const User = createParamDecorator((data, req) => {
  return data ? req.user && req.user[data] : req.user;
});
```

컨트롤러에서 `@User()`데코레이터를 통해 특정 속성에 액세스하는 방법은 다음과 같습니다.

```typescript
@@filename()
@Get()
async findOne(@User('firstName') firstName: string) {
  console.log(`Hello ${firstName}`);
}
@@switch
@Get()
@Bind(User('firstName'))
async findOne(firstName) {
  console.log(`Hello ${firstName}`);
}
```

이 키를 다른 키와 함께 사용하여 다른 속성에 액세스 할 수 있습니다. `user` 객체가 깊거나 복잡한 경우, 더 쉽고 읽기 쉬운 요청 핸들러 구현을 만들 수 있습니다.

## Working with pipes

Nest는 내장 매개 변수 (`@Body()`, `@Param()`및 `@Query()`)와 동일한 방식으로 사용자 정의 매개 변수 데코레이터를 처리합니다. 이는 커스텀 주석 매개 변수 (이 예제에서는 `user` 인수)에 대해서도 파이프가 실행됨을 의미합니다. 또한 파이프를 사용자 정의 데코레이터에 직접 적용 할 수 있습니다.

```typescript
@@filename()
@Get()
async findOne(@User(new ValidationPipe()) user: UserEntity) {
  console.log(user);
}
@@switch
@Get()
@Bind(User(new ValidationPipe()))
async findOne(user) {
  console.log(user);
}
```
