참고: Building RESTful APIs Using Node.js and Express | Coursera
- 이 포스트에서는 coursera의 Building RESTful APIs Using Node.js and Express | Coursera 를 수강하며 배운 주요 개념과 과제를 진행하며 발생한 이슈 해결 방법을 공유합니다.
- 이는 저의 개인적인 이해를 바탕으로 작성되었으며 모든 정보가 최신이거나 완전한 것은 아니므로 항상 개선의 여지가 있습니다. 따라서 읽는 동안 어떤 피드백이나 추가적인 아이디어가 있으시다면 언제든지 댓글로 알려주시기 바랍니다.
3. Swagger로 API 문서화하기
TASK 3
저수준 계층에서 고수준 계층으로 올라가며 구현하는 것이 내게는 더 효율적인 것 같다. 앞선 예제 코드를 충실히 따라했으면 큰 어려움은 없다.
TASK 4
- json-server를 데이터베이스로 사용하기
- controller, routes, service 레이어 정의하기
- get, post, put, delete 메소드로 라우트 구현하기
- morgan을 이용해 logger 미들웨어 구현하기
- 에러 핸들링하는 미들웨어 구현하기
- swagger로 api document 하기
Q. 어디까지가 400 에러이고, 어디부터 500번대 에러인가?
과제하다가 생긴 의문.
프로젝트 구조에 따르면 router -> controller -> service -> DAO 순으로 점점 더 저수준 단계로 내려간다.
에러는 이 중 어느 단계에서도 발생할 수 있는데, 어디부터가 서버 단의 잘못으로 인한 에러가 되는 것인지 스스로 잘 모르고 있다는 사실을 발견했다. (사실상 나는 서버 코드를 짜고 있으니까 다 500번대 에러 아닌가? 싶은 단순한 생각이 들었고…)
우선 HTTP 상태 코드 중 400번대와 500번대를 자세히 살펴보자.
상태 코드 | 설명 |
---|---|
400 Bad Request | 클라이언트의 요청이 유효하지 않아 서버가 이해할 수 없음 |
401 Unauthorized | 클라이언트가 인증되지 않았거나 인증이 실패했음 |
403 Forbidden | 클라이언트가 리소스에 액세스할 권한이 없음 |
404 Not Found | 서버가 요청한 리소스를 찾을 수 없음 |
405 Method Not Allowed | 서버가 알고 있는 메서드이지만, 현재 리소스에 대해서는 사용이 금지됨 |
406 Not Acceptable | 요청 헤더 필드에 의해 정의된 조건이 충족되지 않음 |
429 Too Many Requests | 클라이언트가 주어진 시간동안 너무 많은 요청을 보냄 (Rate Limiting) |
500 Internal Server Error | 서버 내부 오류로 요청을 처리할 수 없음 |
501 Not Implemented | 서버가 요청 메서드를 지원하지 않음 |
502 Bad Gateway | 서버가 게이트웨이 또는 프록시 역할을 하며, 업스트림 서버로부터 잘못된 응답을 받음 |
503 Service Unavailable | 서버가 일시적으로 요청을 처리할 수 없음 |
504 Gateway Timeout | 서버가 게이트웨이 또는 프록시 역할을 하며, 업스트림 서버로부터 시간 내에 응답을 받지 못함 |
505 HTTP Version Not Supported | 서버가 지원하지 않는 HTTP 버전에 대한 요청이 있을 경우 반환됨 |
여기서 제일 헷갈렸던 것은 400 Bad Request와 500 Internerl Server Error의 기준이다.
아래 예제를 통해 설명하겠다.
// 서비스 계층
function validateUser(userId, done) {
if (!userId) {
return done(new Error('User ID is required'));
}
if (typeof userId !== 'number') {
return done(new Error('User ID must be a number'));
}
// 필요한 경우 더 많은 검증을 추가할 수 있습니다
done(null);
}
// 컨트롤러 계층
app.get('/users/:id', (req, res) => {
const userId = parseInt(req.params.id);
validateUser(userId, (err) => {
if (err) {
console.error('Error occurred:', err);
return res.status(400).send(err.message);
}
getUser(userId, (err, user) => {
if (err) {
console.error('Error occurred:', err);
return res.status(500).send('Internal Server Error');
}
res.json(user);
});
});
});
- 400 bad request 에러:
- 서버가 요청을 처리하기 위해 필요한 요구 조건들을 갖추지 않고 클라이언트가 요청을 보낸 경우
- 서비스 계층에서 클라이언트가 넘겨준 데이터에 대해 검증하고 이때 통과하지 못하면 400 bad request를 반환함
- 예: 필요한 파라미터가 누락된 경우, 잘못된 JSON 형식을 보낸 경우(구문 오류), 데이터 유형 불일치, 존재하지 않는 메소드로 요청을 보내는 경우 등
- 500 번대 에러:
- 위와 같은 요청에 대한 validation을 통과한 후의 로직에서 발생하는 에러는(예: 데이터베이스 연결 오류) 500번대 에러로 처리함.
여기서 핵심은 서버가 요청의 말귀를 이해하지 못하는 것이 400번 에러라는 점.