# 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);
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://jakekwak.gitbook.io/nestjs/overview/custom-decorators.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
