> For the complete documentation index, see [llms.txt](https://tech.x2bee.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://tech.x2bee.com/dev-guide/dev-start/images-and-media/undefined-2.md).

# 유효성 체크

**X2BEE 솔루션**에서 **Zod 라이브러리**를 사용해 데이터 유효성을 검증합니다. 본 가이드는 스키마 정의, 필드별 유효성 검증, 전체 데이터 검증, 데이터 가공 및 타입 추론을 효율적으로 구현하는 방법을 설명합니다.

***

{% stepper %}
{% step %}

### Zod 스키마 정의 방법

Zod는 TypeScript를 우선으로 하는 스키마 선언 및 유효성 검증 라이브러리이며, 중복된 유형 선언을 제거하기 위해 사용됩니다. Zod를 통해 유효성 검사를 하고 TypeScript 유형을 추론할 수 있습니다.

{% code title="예시: 기본 객체 스키마" %}

```javascript
import { z } from 'zod'

/** 기본적인 zod 객체 선언은 내부에 object 함수를 이용하여 객체를 생성하고 반환해줄 수 있습니다.
    Argument로 객체를 던져주면 상수 형태의 zod schema를 사용할 수 있습니다.
    Argument로 전달하는 객체의 경우 각 필드를 정의하고 타입을 zod의 타입으로 정의해줘야 합니다.
**/
const zodExampleSchema = z.object({
  name: z.string(),
  userId: z.string(),
  password: z.string(),
  phone: z.number()
})
```

{% endcode %}
{% endstep %}

{% step %}

### 각 필드별 유효성 체크 방법

Zod만으로는 일부 자유도 높은 검증에 제한이 있으므로, 각 항목에 대해 refine를 사용한 필드별 커스텀 검증을 적용할 수 있습니다. 아래는 빈 값 체크 등 기본적인 검증 예시입니다.

{% code title="예시: refine를 이용한 필드 검증" %}

```javascript
import { z } from 'zod'

/** min, max 등 다양한 기본 검증 방식들이 존재하지만,
    자유도 있는 검증을 위해 zod의 refine를 이용할 수 있습니다.
    refine의 첫번째 인자는 검증 통과 여부(boolean)를 반환하는 함수,
    두번째 인자는 메시지 등의 옵션입니다.
**/
const zodExampleSchema = z.object({
  name: z.string().refine(
    (data) => !!data, // data는 name 필드의 값을 의미 (boolean 반환)
    {
      message: "이름을 입력해주세요."
    }
  ),
  userId: z.string(),
  password: z.string(),
  phone: z.number()
})
```

{% endcode %}
{% endstep %}

{% step %}

### 전체 필드를 대상으로 한 유효성 체크 방법

필드 간 참조가 필요한 검증(예: 비밀번호와 비밀번호 확인 일치 여부)은 개별 필드의 refine로는 어려우므로, object 레벨에서 superRefine를 사용합니다. superRefine는 전체 데이터 객체와 컨텍스트를 받아 복합 검증을 수행할 수 있습니다.

{% code title="예시: superRefine를 이용한 전체 필드 검증" %}

```javascript
import { z } from 'zod'

/** superRefine는 z.object에 적용되는 함수로,
    첫번째 인자는 전체 필드 데이터를 가진 객체,
    두번째 인자는 zod의 context(ctx) 입니다.
**/
const zodExampleSchema = z.object({
  userId: z.string(),
  password: z.string(),
  rePassword: z.string()
}).superRefine((data, ctx) => {
  if (data.password !== data.rePassword) {
    ctx.addIssue({
      message: "비밀번호가 일치하지 않습니다.",
      code: z.ZodIssueCode.custom,
      path: ['password']
    })
    return false
  }
  return true
})
```

{% endcode %}
{% endstep %}

{% step %}

### 최종 스키마 데이터 가공 방법

검증 후 반환되는 데이터를 변환하거나 불필요한 필드를 제거하는 등 스키마 레벨에서 데이터를 가공하려면 transform을 사용합니다. transform은 검증이 통과된 후 최종값으로 변환된 객체를 반환합니다. 필요하다면 transform 전에 데이터를 가공하고 superRefine로 검증할 수도 있습니다.

{% code title="예시: superRefine + transform" %}

```javascript
import { z } from 'zod'

/** 아래 예시는 아이디 비어있음 체크, 비밀번호 확인 검사 후
    transform로 최종 반환값을 가공하는 예시입니다.
**/
const zodExampleSchema = z.object({
  userId: z.string().refine(
    (data) => !!data,
    { message: "아이디를 입력해주세요." }
  ),
  password: z.string(),
  rePassword: z.string()
}).superRefine((data, ctx) => {
  if (data.password !== data.rePassword) {
    ctx.addIssue({
      message: "비밀번호가 일치하지 않습니다.",
      code: z.ZodIssueCode.custom,
      path: ['password']
    })
    return false
  }
  return true
}).transform((data) => {
  return {
    userId: data.userId,
    password: data.password
  }
})
```

{% endcode %}
{% endstep %}

{% step %}

### 타입 추론 방법

Zod 스키마로부터 TypeScript 타입을 추론하려면 z.infer를 사용합니다.

{% code title="예시: z.infer로 타입 추론" %}

```javascript
import { z } from 'zod'

/** Typescript 변환 예시 **/
const zodExampleSchema = z.object({
  // ...스키마 정의
})

// Typescript type
type zodExampleType = z.infer<typeof zodExampleSchema>
```

{% endcode %}
{% endstep %}
{% endstepper %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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://tech.x2bee.com/dev-guide/dev-start/images-and-media/undefined-2.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.
