DB와 연결하고 포스트맨으로 API 테스트를 하던 중, 회원 등록 요청에서 아래와 같은 오류가 오류가 발생했다.
ValidationError: User validation failed: password: Path `password` is required., email: Path `email` is required.
↑ 오류 메시지
같이 확인해볼 코드는 register API, userSchema 코드와 포스트맨에서 보낸 request body(req.body), response body 부분이다.
// 회원 등록
app.post('/api/user/register', (req, res) => {
try {
const user = new User(req.body);
console.log(user);
const userData = user.save();
return res.status(200).json({ success: true, user:userData});
} catch {
return res.status(400).json({ success: false, err});
}
})
↑ register API (오류 발생)
const userSchema = mongoose.Schema({ // schema 필드 정의
name: {
type: String,
maxLength: 50
},
email: {
type: String,
required: true,
unique: true,
lowercase: true,
trim: true // 앞뒤 공백 제거
},
password: {
type: String,
required: true,
trim: true,
minLength: 5
},
role: {
type: Number,
default: 0
}
})
↑ userSchema
{
"name": "amanda",
"email": "amanda@gmail.com",
"password": "1234567"
}
↑ Postman - request body(req.body)
{
"success": true,
"user": {}
}
↑ Postman - response body
🚧 원인 분석
userSchema에서 email, password를 required: true
를 설정하고 Postman에서 email, password의 값을 포함해 요청을 보냈음에도, Mongoose는 이 필드가 없다고 판단하며 validation 오류를 발생시킨 것이다.
Express는 기본적으로 요청 본문을 자동으로 파싱하지 않기 때문에, JSON 형식의 요청을 받을 경우 body-parser
과 같은 미들웨어를 추가해줘야 req.body가 제대로 채워진다. 그래서 내가 작성한 코드로는 req.body
가 undefined 였고, new User(req.body)에 들어가는 값도 비어 있으며, email과 password가 누락된 채 validation에 걸리게 된 것이다.
🛠️ 해결 과정
1. body-parser 미들웨어 추가
body-parser 모듈을 설치한다.
npm install body-parser
이후 코드 상단에 아래와 같이 등록한다.
const bodyParser = require('body-parser'); // HTTP 요청 본문(body) 파싱하는 미들웨어 불러오기
app.use(bodyParser.urlencoded( { extended: true })); // application/x-www-form-urlencoded
app.use(bodyParser.json()); // application/json
↑ register API
여기서 사용한 extended 옵션은 false가 기본이고, false를 설정할 경우 Node.js 기본 모듈인 querystring
을 사용해 단순 구조만 파싱한다. true로 설정하면 qs
라이브러리를 사용해서 중첩된 객체나 배열 등 복잡한 구조도 파싱할 수 있다.
여기까지 설정하면 JSON 데이터를 정상적으로 받을 수 있게 된다.
2. async/await 적용
body-parser를 추가해도 여전히 Postman 응답에서 "user": {}처럼 빈 객체가 보였다. Mongoose의 user.save()가 비동기 함수인데 await를 붙이지 않아 저장이 완료되기 전에 응답을 보냈기 때문이다.
// 회원 등록
const bodyParser = require('body-parser'); // HTTP 요청 본문(body) 파싱하는 미들웨어 불러오기
app.use(bodyParser.urlencoded( { extended: true })); // application/x-www-form-urlencoded
app.use(bodyParser.json()); // application/json
app.post('/api/user/register', async (req, res) => {
try {
const user = new User(req.body);
console.log(user);
const userData = await user.save();
return res.status(200).json({ success: true, user:userData});
} catch {
return res.status(400).json({ success: false, err});
}
})
↑ register API
Mongoose의 save()
는 Promise를 반환하며, 내부적으로 저장 전에 validation을 자동으로 실행한다.
await
을 사용하지 않으면 저장이 완료되기도 전에 응답을 보내는 문제가 생길 수 있다.
이 경우 user.save()
는 아직 실행 중인 Promise이므로, 응답에서 user: {}
처럼 보일 수 있다.
따라서 await
을 사용해 저장이 완료된 후 응답을 보내야 한다.
🧠 What I Learned
Express는 요청 본문을 파싱해주는 미들웨어가 필요하다. body-parser.json()
을 등록하지 않으면 JSON 형식으로 보낸 데이터도 undefined 처리되어 validation 오류가 발생할 수 있다. user.save()
는 비동기 함수이므로, 저장 완료를 보장하려면 await를 사용한다.
'Troubleshooting' 카테고리의 다른 글
How to Edit Git Commit Messages - amend, rebase 정리 (0) | 2025.07.28 |
---|---|
How to Fix a Leaked MongoDB Atlas Database URI with Credentials (1) | 2025.07.27 |
Template Error: Couldn't find user script folder "Scripts" - Obsidian (3) | 2025.07.25 |
Image elements do not have alt attributes 해결 - Lighthouse 성능 최적화 (0) | 2025.05.07 |
🛠️ Git 관련 오류 해결 (0) | 2025.05.06 |