Joi [ TIL ] [ node.js ]

2023. 7. 3. 21:49TIL&WIL/TIL

 

Problem

 

api 를 만들때 일일이 if 로 유효성검사하는 것이 불편하였다.


Try

 

괜찮은 라이브러리가 있나 npm 에서 찾아보았습니다.

validation 을 검색했는데 인기있어보이는 라이브러리가 두 개 있었다.

express-validator 와 joi 라는 것이 눈에 띄었는데, 둘 중 다운로드 수가 가장 많은 joi 를 선택했다.

const Joi = require('joi');

const schema = Joi.object({
    username: Joi.string()
        .alphanum()
        .min(3)
        .max(30)
        .required(),

    password: Joi.string()
        .pattern(new RegExp('^[a-zA-Z0-9]{3,30}$')),

    repeat_password: Joi.ref('password'),

    access_token: [
        Joi.string(),
        Joi.number()
    ],

    birth_year: Joi.number()
        .integer()
        .min(1900)
        .max(2013),

    email: Joi.string()
        .email({ minDomainSegments: 2, tlds: { allow: ['com', 'net'] } })
})
    .with('username', 'birth_year')
    .xor('password', 'access_token')
    .with('password', 'repeat_password');


schema.validate({ username: 'abc', birth_year: 1994 });
// -> { value: { username: 'abc', birth_year: 1994 } }

schema.validate({});
// -> { value: {}, error: '"username" is required' }

// Also -

try {
    const value = await schema.validateAsync({ username: 'abc', birth_year: 1994 });
}
catch (err) { }

요로코롬 예시가 적혀있는 모습이다.

 

출처 : https://joi.dev/api/?v=17.9.1 

 

joi.dev

 

joi.dev

 

하나씩 써보면서 회원가입 api 를 만들어 보았다.

 

 


Solve

 

const signupValidation = Joi.object({
  nickname: Joi.string().not("").alphanum().required().messages({
    "any.only": "닉네임의 형식이 일치하지 않습니다.",
  }),
  password: Joi.string().not("").min(3).required().messages({
    "string.base": "비밀번호 형식이 일치하지 않습니다.",
    "any.required": "비밀번호를 입력해주세요.",
  }),
  confirmPassword: Joi.equal(Joi.ref("password")).not("").required().messages({
    "any.only": "비밀번호가 일치하지 않습니다.",
    "any.required": "confirm 을 입력해주세요",
  }),
});

string() 으로 문자열을 받고,

not() 으로 빈 문자열은 받지 않는다.

alphanum() 으로 알파벳과 숫자만 입력 가능하고,

required() 로 없으면 에러가 발생하게 한다.

messages 에는 어떤 에러를 포함할건지를 적을 수 있다.

 

Joi 덕분에 에러처리가 더욱 편리해진 느낌이다.

// 회원 가입 api
router.post("/", async (req, res) => {
  try {
    const { nickname, password, confirmPassword } =
      await signupValidation.validateAsync(req.body);

    // ...중략
    await Users.create({
      nickname,
      password: hashedPassword,
    });

    return res.status(201).json({ message: "회원 가입에 성공하였습니다." });
  } catch (err) {
    if (err.isJoi) {
      return res.status(412).json({ errorMessage: err.details[0].message });
    }
    console.error(err);
  }
});

 


What I Learned

 

Joi 라이브러리에 대해서 익힐 수 있었다. 아주 일부분만 익혔지만 더 익히면 joi 가 굉장히 편리할 것같다.

어떤 방식으로 joi 를 사용하면 되는지 joi 에서 에러는 어떻게 표시되고 어떻게 원하는대로 출력할 수 있는지 알게되었다.

 

'TIL&WIL > TIL' 카테고리의 다른 글

ORM [ TIL ]  (0) 2023.07.09
HTTP 상태코드 [ TIL ]  (0) 2023.07.05
package.json [ TIL ]  (0) 2023.07.02
HTTP [ TIL ]  (0) 2023.07.01
객체 지향 프로그래밍 OOP [ TIL ]  (0) 2023.06.28