[TIL] Joi

sooyoung choi·2023년 11월 19일
0

Javascript, Node.js

목록 보기
22/37
post-thumbnail

노드 마켓 서버 만들기 과제 중 스키마 관련 유효성 검사를 해주는 라이브러리를 알게되어 적용해보았다!

🤷‍♀️ Joi?

  • 스키마 관련 유효성 검사를 해주는 라이브러리
  • 예를들어 해당 서비스 유저의 요청에 유저의 이메일, 닉네임, 패스워드나 상품의 이름, 가격 등은 필수적으로 적어야 하는 값을 넣지 않았을 때 Joi가 ValidationError이라는 에러 이름을 통해 걸러준다!
  • 공식문서 https://joi.dev/api/?v=17.9.1

👨‍💻 내 프로젝트에 적용해보기

상품 스키마

FieldTypeNullKeyDefaultExtra
productIdintNOPRInullauto_increment
UserIdintNOMULnull
titlevarchar(255)NOnull
contentvarchar(255)NOnull
priceintNOnull
statusvarchar(255)NOFOR_SALE
createdAtdatetimeNOCURRENT_TIMESTAMPDEFAULT_GENERATED
updatedAtdatetimeNOCURRENT_TIMESTAMPDEFAULT_GENERATED

  • Joi 설치
yarn add joi
npm i joi

  • Joi 에러 핸들러 설계
  • title, content, price, status 값은 유저에게 요청받아야 하는 값!
  • productSchemaValidation 이름으로 다른 파일에서도 쓸 수 있게 내보내줬다.
// ProductJoiSchema.js

const Joi = require("joi");

const productSchemaValidation = Joi.object({
    title: Joi.string().required(),	// string값, 꼭 받아야 하는 값
    content: Joi.string().required(),
    price: Joi.number().required(),	// integer 값
    status: Joi.string().required(),
});

module.exports = { productSchemaValidation };

  • 상품 라우터에서 에러를 잡아낼 수 있게 상품 글 생성 라우터 부분에 Joi를 추가해줬다.
// products.router.js

...

// 상품 글 생성
router.post("/products/new", authMiddleware, async (req, res, next) => {
    try {
        const { userId } = res.locals.user;

        const { title, content, price, status } =
            await productSchemaValidation.validateAsync(req.body);

        // Joi를 쓰기전에는 따로 에러처리를 해줬었다.
        // if (!title || !content || price <= 0 || !status) {
        //     const error = new QuerySyntaxError();
        //     throw error;
        // }

        const product = await Products.create({
            UserId: userId,
            title,
            content,
            price,
            status,
        });

        return res.status(201).json({ data: product });
    } catch (error) {
        next(error);
    }
});

...

  • 에러 처리 미들웨어에서 해당 에러가 나타났을 때 어떤 에러인지 보여주기 위해 상태코드와 함께 json 값으로 에러메세지를 출력해줬다.
// error-middleware.js
// PRODUCT
// CREATE

...

if (req.route.path === "/products/new") {
  if (err.name === "QuerySyntaxError") {
    return res
      .status(401)
      .json({ message: "데이터 형식이 올바르지 않습니다." });
  }

  if (err.name === "ValidationError") {
    res.status(412);
    if (err.details[0].path[0] === "title") {
      return res.json({ message: "제목을 작성해주세요." });
    }
    if (err.details[0].path[0] === "content") {
      return res.json({ message: "내용을 작성해주세요." });
    }
    if (err.details[0].path[0] === "price") {
      return res.json({ message: "가격을 작성해주세요." });
    }
    if (err.details[0].path[0] === "status") {
      return res.json({ message: "상품 판매 상태를 작성해주세요." });
    }
  }
}

...

  • 결과(굳굳👍)
  • 일일이 에러 이름을 만들어주고 하나하나 에러처리를 해줬었던거에 비해 간단하게 유효성 검사를 할 수 있게 되었다!



하지만 user 관련 Joi 부분은 해결하지 못했다ㅠ Product랑 똑같이 해줬는데 왜그르냐 confirmpassword 값 받는 거 때문인건지 TypeError: userSchemaValidation is not a function을 자꾸 뿜어내는디...?

0개의 댓글