2025년 1월 10일

김동환·2025년 1월 10일

오늘의 코드

import Joi from 'joi';
import { MESSAGES } from '../../constants/message.constant.js';
import { MIN_RESUME_LENGTH } from '../../constants/resume.constant.js';

// 조이 오브젝트라는 메서드 이용해서 타이틀과 컨텐트를 검증할 스키마를 만든다.
const schema = Joi.object({
  title: Joi.string().required().messages({
    'any.required': MESSAGES.RESUMES.COMMON.TITLE.REQUIRED,
  }),
  content: Joi.string().min(MIN_RESUME_LENGTH).required().messages({
    'any.required': MESSAGES.RESUMES.COMMON.CONTENT.REQUIRED,
    'string.min': MESSAGES.RESUMES.COMMON.CONTENT.MIN_LENGTH,
  }),
});

// createResumeValidator 를 진짜로 실행할 수 있는 벨리데이트 함수를 만들었다.
export const createResumeValidator = async (req, res, next) => {
  try {
    await schema.validateAsync(req.body);
    next();
  } catch (error) {
    next(error);
  }
};

TIL (Today I Learned): Joi를 사용한 요청 데이터 유효성 검사 구현

오늘 배운 내용

Joi를 사용해 요청 데이터의 유효성을 검사하는 방법을 학습했다. 이를 바탕으로 createResumeValidator 함수를 구현하여 특정 필드의 데이터 형식과 조건을 검증할 수 있다. 주요 내용은 아래와 같다.


1. Joi 스키마 정의

Joi.object() 메서드를 사용해 titlecontent 필드의 유효성을 정의한다.

스키마 구성 요소

  • title 필드

    • 문자열이어야 하며 필수 입력값(required)이다.
    • 유효하지 않은 경우 MESSAGES.RESUMES.COMMON.TITLE.REQUIRED 메시지가 반환된다.
  • content 필드

    • 최소 길이가 MIN_RESUME_LENGTH 이상이어야 한다.
    • 필수 입력값이며, 유효하지 않은 경우 아래와 같은 메시지가 반환된다:
      • MESSAGES.RESUMES.COMMON.CONTENT.REQUIRED: 필드가 비어 있을 때.
      • MESSAGES.RESUMES.COMMON.CONTENT.MIN_LENGTH: 최소 길이를 충족하지 못했을 때.

예시 코드

const schema = Joi.object({
  title: Joi.string().required().messages({
    'any.required': MESSAGES.RESUMES.COMMON.TITLE.REQUIRED,
  }),
  content: Joi.string().min(MIN_RESUME_LENGTH).required().messages({
    'any.required': MESSAGES.RESUMES.COMMON.CONTENT.REQUIRED,
    'string.min': MESSAGES.RESUMES.COMMON.CONTENT.MIN_LENGTH,
  }),
});

2. Validator 함수 구현

createResumeValidator 함수는 요청(req)의 body를 검증하며, 성공하면 다음 미들웨어로 넘어가고, 실패 시 에러를 next 함수로 전달한다.

구현 흐름

  1. schema.validateAsync(req.body)를 호출해 req.body를 스키마에 따라 검증한다.
  2. 검증이 성공하면 next()를 호출해 다음 미들웨어로 이동한다.
  3. 검증이 실패하면 발생한 에러(error)를 next(error)로 전달하여 에러 처리 미들웨어에서 처리하도록 한다.

예시 코드

export const createResumeValidator = async (req, res, next) => {
  try {
    await schema.validateAsync(req.body);
    next();
  } catch (error) {
    next(error);
  }
};

3. 코드의 활용

  • 유효성 검사 메시지 관리: 에러 메시지는 MESSAGES 상수에서 관리되므로 일관성을 유지할 수 있다.
  • 재사용성: Joi 스키마는 별도로 정의되어 있어 다른 컨텍스트에서도 재사용 가능하다.
  • 비동기 처리: validateAsync 메서드를 사용해 비동기 검증을 수행한다.

4. 오늘의 깨달음

  • Joi를 사용하면 명확하고 직관적인 방식으로 유효성 검사를 구현할 수 있다.
  • 요청 데이터의 유효성 검사는 서버의 안정성과 사용자 경험을 보장하는 중요한 부분이다.
  • 에러 처리를 일관성 있게 구현하면 디버깅과 유지보수가 쉬워진다.

앞으로는 다양한 스키마 검증 규칙을 추가적으로 학습하고, 실무에 적용할 때 어떻게 커스터마이징할 수 있는지 더 살펴볼 예정이다.


2번째 코드

import Joi from 'joi'; // 데이터 유효성 검사를 위한 Joi 라이브러리
import { MESSAGES } from '../../constants/message.constant.js'; // 응답 메시지 상수
import { MIN_RESUME_LENGTH } from '../../constants/resume.constant.js'; // 이력서 내용의 최소 길이 상수

// Joi 스키마 정의: 이력서 업데이트를 위한 데이터 유효성 검사
const schema = Joi.object({
  // 제목 (title): 문자열 (필수 아님)
  title: Joi.string(),
  // 내용 (content): 문자열이며 최소 길이 요구
  content: Joi.string().min(MIN_RESUME_LENGTH).messages({
    // 내용의 최소 길이 미만일 경우 에러 메시지 설정
    'string.min': MESSAGES.RESUMES.COMMON.CONTENT.MIN_LENGTH,
  }),
})
  .min(1) // 최소 1개 이상의 필드가 요청 본문에 포함되어야 함
  .messages({
    // 본문이 비어 있을 경우 에러 메시지 설정
    'object.min': MESSAGES.RESUMES.UPDATE.NO_BODY_DATA,
  });

// 이력서 업데이트 요청을 검증하는 미들웨어 함수
export const updateResumeValidator = async (req, res, next) => {
  try {
    // 요청 본문(req.body)을 정의된 스키마를 통해 비동기로 검증
    await schema.validateAsync(req.body);
    // 검증 성공 시 다음 미들웨어로 이동
    next();
  } catch (error) {
    // 검증 실패 시 오류를 다음 미들웨어로 전달
    next(error);
  }
};

TIL (Today I Learned): Joi를 사용한 이력서 업데이트 요청 유효성 검사


오늘 배운 내용

Joi 라이브러리를 사용해 이력서 업데이트 요청 데이터를 검증하는 방법을 학습했다. 이를 통해 특정 필드가 조건을 만족하도록 보장하며, 요청 데이터의 형식적 일관성을 유지할 수 있다.


1. Joi 스키마 정의

이력서 업데이트를 위해 Joi.object()를 활용하여 데이터 검증 스키마를 정의했다. 업데이트 요청은 모든 필드가 필수가 아니며, 최소 한 개 이상의 필드가 포함되어야 한다.

스키마 구성

  1. title 필드

    • 문자열(string()) 타입.
    • 필수 항목이 아니므로 값이 없어도 허용된다.
  2. content 필드

    • 문자열(string()) 타입.
    • 최소 길이는 MIN_RESUME_LENGTH로 제한된다.
    • 조건을 충족하지 못하면 MESSAGES.RESUMES.COMMON.CONTENT.MIN_LENGTH 메시지가 반환된다.
  3. 요청 본문

    • 최소 1개 이상의 필드가 포함되어야 한다(.min(1)).
    • 본문에 아무 데이터도 없을 경우 MESSAGES.RESUMES.UPDATE.NO_BODY_DATA 메시지가 반환된다.

스키마 코드

const schema = Joi.object({
  title: Joi.string(),
  content: Joi.string().min(MIN_RESUME_LENGTH).messages({
    'string.min': MESSAGES.RESUMES.COMMON.CONTENT.MIN_LENGTH,
  }),
})
  .min(1)
  .messages({
    'object.min': MESSAGES.RESUMES.UPDATE.NO_BODY_DATA,
  });

2. Validator 함수 구현

updateResumeValidator 함수는 요청 데이터(req.body)를 스키마에 따라 검증한다. 요청 데이터가 유효한 경우에만 다음 미들웨어로 넘어간다.

구현 흐름

  1. schema.validateAsync(req.body) 호출:
    • 요청 본문을 정의된 스키마에 따라 비동기로 검증한다.
  2. 검증 성공:
    • next()를 호출하여 다음 미들웨어로 이동한다.
  3. 검증 실패:
    • 발생한 오류를 next(error)로 전달하여 에러 처리 미들웨어에서 처리한다.

Validator 함수 코드

export const updateResumeValidator = async (req, res, next) => {
  try {
    await schema.validateAsync(req.body);
    next();
  } catch (error) {
    next(error);
  }
};

3. 주요 특징

  • 유연한 데이터 구조: 이력서 업데이트 요청은 부분 업데이트를 허용하므로, 필드의 필수 여부를 개별적으로 설정하지 않았다.
  • 요청 본문 유효성 보장: 본문에 최소 한 개의 데이터가 포함되어야 함을 명시하여 빈 요청을 방지한다.
  • 에러 메시지 커스터마이징: 에러 상황에 따라 명확한 메시지를 반환하여 디버깅과 사용자 경험을 개선했다.

4. 적용 사례

이 코드는 RESTful API에서 이력서를 업데이트하는 엔드포인트에 사용될 수 있다. 예를 들어, 아래와 같은 요청이 있을 경우:

PATCH /resumes/1
{
  "content": "Updated resume content."
}

content 필드가 MIN_RESUME_LENGTH 이상인 경우에만 성공적으로 처리된다. 데이터가 유효하지 않으면 적절한 에러 메시지가 반환된다.


5. 오늘의 깨달음

  • Joi의 강력한 유효성 검사 기능: 다양한 조건을 설정하고 메시지를 커스터마이징하여 유효성 검사를 직관적이고 간결하게 구현할 수 있다.
  • 비동기 검증: validateAsync를 통해 비동기로 데이터를 검증하며, 요청 데이터의 처리 흐름을 방해하지 않는다.
  • 유효성 검사 중요성: 클라이언트에서 비정상적인 데이터가 서버에 도달하지 않도록 함으로써, API의 신뢰성과 보안을 향상시킬 수 있다.

앞으로 더 복잡한 검증 규칙이나 동적 조건을 추가해 실무 프로젝트에서 활용할 계획이다.

profile
Node.js 7기

0개의 댓글