핸들러(Handler)
요청에 의해서 실행되는 메서드를 말한다.
예시로, 아래 코드에서 get 메서드의 두 번째 파라미터인 콜백 함수가 핸들러이다. HTTP Request가 날아오면 자동으로 호출된다.
app.get('/', function (req, res) {
res.send('Hello World');
})
==과 ===
==은 값이 일치하는지만 확인하지만, ===은 자료형과 값 모두 일치하는지 확인한다.
// 자료형은 상관 없이 값만 비교
if (1 == '1') {
console.log('같다');
} else {
console.log('다르다');
}
// 값과 자료형 모두 비교
if (1 === '1') {
console.log('같다');
} else {
console.log('다르다');
}
예외 처리
클린 코드 관점에서 조건문은 긍정문인 것이 더 간결한다. 아래 코드는 과일을 개별 조회할 때 저장되어 있는 id가 없을 경우 예외 처리해 주는 코드이다.
배열의 메서드인 find 함수는 조건에 처음으로 해당하는 원소를 반환해 준다. 조건과 일치하는 원소가 없을 경우 undefined가 반환된다.
존재하지 않는 id에 대한 요청이 오면 HTTP 상태 코드를 404로 설정한다. 상태 코드는 클라이언트와 정확하게 소통하기 위해 설정한다. 이때 클라이언트는 사용자나 화면이다.
const express = require('express');
const app = express();
app.listen(3000);
const fruits = [
{ id: 1, name: 'apple' },
{ id: 2, name: 'orange' },
{ id: 3, name: 'grape' },
{ id: 4, name: 'lemon' }
];
// 과일 전체 조회
app.get('/fruits', (req, res) => {
res.json(fruits);
})
// 과일 개별 조회
app.get('/fruits/:id', (req, res) => {
const id = parseInt(req.params.id);
// fruits 배열 안에 있는 객체 중, id 값이 params.id랑 같은 객체
const fruit = fruits.find(value => value['id'] === id);
if (fruit) {
res.json(fruit);
} else {
res.status(404).send('전달주신 id로 저장된 과일이 없습니다.')
}
})
Youtuber Demo의 고도화
HTTP 상태 코드를 설정하고, 예외 처리를 추가로 해주었다.
전체 유튜버 조회
DB가 비어있을 때에 대한 예외처리와 그때의 상태 코드를 찾는 리소스가 없다는 의미인 404로 설정한다.
app.get('/youtubers', function (req, res) {
const youtubers = {};
if (db.size) {
db.forEach(function (youtuber, id) {
youtubers[id] = youtuber;
})
res.json(youtubers);
} else {
res.status(404).json({
message: "조회할 유튜버가 없습니다."
});
}
})
유튜버 등록
채널명의 누락 여부를 확인하고, 누락되었을 경우 잘못된 요청이라는 의미의 상태 코드 400과 함께 메시지를 발송한다. 누락되지 않은 경우에는 등록을 정상적으로 수행했다는 의미로 상태 코드를 201로 설정한다.
app.post('/youtubers', function (req, res) {
const channelTitle = req.body.channelTitle;
if (channelTitle) {
db.set(id++, { channelTitle: channelTitle, sub: 0, videoNum: 0 }); // db에 등록
res.status(201).json({
message: `${db.get(id - 1).channelTitle}님, 유튜버 생활을 응원합니다!`
});
} else {
res.status(400).json({
message: '요청 값을 제대로 보내주세요.'
});
}
})
전체 유튜버 삭제
DB가 비었는지 먼저 확인한다. 비어있지 않은 경우에는 상태 코드를 설정하지 않았는데, 기본 값이 200이기 때문이다. 200은 조회/삭제/수정이 정상적으로 이루어졌음을 의미한다. DB가 비어있는 경우 상태 코드를 404로 설정한다.
app.delete('/youtubers', function (req, res) {
if (db.size) {
db.clear();
res.json({
message: '전체 유튜버가 삭제되었습니다.'
});
} else {
res.status(404).json({
message: '삭제할 유튜버가 없습니다.'
})
}
})
개별 유튜버 조회
존재하지 않는 id에 대한 조회 요청일 경우 상태 코드를 404로 설정한다.
app.get('/youtubers/:id', function (req, res) {
const id = parseInt(req.params.id);
const youtuber = db.get(id);
if (youtuber) {
res.json({ id: id, ...youtuber });
} else {
res.status(404).json({
message: `요청하신 ${id}번은 없는 유튜버입니다.`
});
}
})
개별 유튜버 삭제
존재하지 않는 id에 대한 삭제 요청일 경우 상태 코드를 404로 설정한다.
app.delete('/youtubers/:id', function (req, res) {
const id = parseInt(req.params.id);
const youtuber = db.get(id);
let msg = '';
if (youtuber) {
const channelTitle = youtuber.channelTitle;
db.delete(id);
res.json({
message: `${channelTitle}님, 아쉽지만 다음에 또 뵙겠습니다.`
})
} else { // undefined
res.status(404).json({
message: `요청하신 ${id}번은 없는 유튜버입니다.`
})
}
})
개별 유튜버 수정
request body가 비어있는 경우 상태 코드 400을, 요청받은 id가 존재하지 않는 경우 상태 코드를 404로 설정한다.
app.put('/youtubers/:id', function (req, res) {
const id = parseInt(req.params.id);
const newChannelTitle = req.body.channelTitle;
const youtuber = db.get(id);
if (youtuber && newChannelTitle) {
const oldChannelTitle = youtuber.channelTitle;
youtuber.channelTitle = newChannelTitle;
db.set(id, youtuber);
res.json({
message: `${oldChannelTitle}님, 채널명이 ${newChannelTitle}으로 변경되었습니다.`
})
} else if (!newChannelTitle) { // 채널명이 누락된 경우
res.status(400).json({
message: `${newChannelTitle}은 잘못된 채널명입니다.`
})
} else { // DB에 존재하지 않는 경우
res.status(404).json({
message: `요청하신 ${id}번은 없는 유튜버입니다.`
});
}
})
미니 프로젝트 - 유튜브 데모
요구사항
회원
- 로그인
- 회원가입
- 회원 정보 조회
- 회원 탈퇴
채널
회원은 계정 1개 당 채널 100개를 가질 수 있다.
- 채널 생성
- 채널 수정
- 채널 삭제
회원 API 설계
기능 | 메서드 | 경로 | 요청 | 응답 |
로그인 | POST | /login | id, password | 환영 메시지 → 메인 페이지 |
회원가입 | POST | /join | id, password, name | 환영 메시지 → 로그인 페이지 |
회원 개별 조회 | GET | /users/:id | id | id, name |
회원 개별 탈퇴 | DELETE | /users/:id | id | 탈퇴 메시지 또는 메인 페이지 |
DB
정수인 id와 회원 정보 객체를 쌍으로 저장한다. 일단 id 변수는 사용자의 id를 의미하지 않는다.
const db = new Map();
let id = 1;
회원가입
request의 body가 비어있는지 확인한다. 비어있다면 상태코드를 400으로 설정하고 메시지를 발송한다. 정상적인 body인 경우 데이터베이스에 저장하고 상태코드를 201로 설정하여 환영 메시지를 전송한다.
app.post('/join', (req, res) => {
if (Object.keys(req.body).length) {
db.set(id++, req.body)
res.status(201).json({
message: `${db.get(id - 1).userId}님, 환영합니다!`
})
} else {
res.status(400).json({
message: "입력 값을 다시 확인해주세요."
})
}
})
회원 개별 조회
id가 DB에 존재하는지 확인하고, 존재할 경우 상태 코드 200, 없을 경우 상태 코드 404로 설정하여 응답 메시지를 발송한다.
app.get('/users/:id', (req, res) => {
const userId = parseInt(req.params.id);
const user = db.get(userId);
if (user) {
res.status(200).json({
userId: user['userId'],
name: user['name']
})
} else {
res.status(404).json({
message: "회원 정보가 없습니다."
})
}
})
회원 개별 탈퇴
id가 존재하는지 확인하고, 존재하면 삭제 후 메시지를 전송하고, 존재하지 않으면 상태 코드를 404로 설정하여 메시지를 전송한다.
app.delete('/users/:id', (req, res) => {
const userId = parseInt(req.params.id);
const user = db.get(userId);
if (user) {
db.delete(id);
res.status(200).json({
message: `${user['name']}님, 다음에 또 뵙겠습니다.`
})
} else {
res.status(404).json({
message: "회원 정보가 없습니다."
})
}
})
route 메서드
경로는 동일한데 메서드만 다르다면 express의 route 메서드로 한 곳에 모아 라우팅 할 수 있다.
현재까지 만든 기능 중에서는 회원 개별 조회와 회원 개별 탈퇴 기능의 경로가 동일하다. 그래서 앞서 사용한 코드를 다음과 같이 수정해도 동일하게 동작한다.
app.route('/users/:id')
.get((req, res) => {
const userId = parseInt(req.params.id);
const user = db.get(userId);
if (user) {
res.status(200).json({
userId: user['userId'],
name: user['name']
})
} else {
res.status(404).json({
message: "회원 정보가 없습니다."
})
}
})
.delete((req, res) => {
const userId = parseInt(req.params.id);
const user = db.get(userId);
if (user) {
db.delete(id);
res.status(200).json({
message: `${user['name']}님, 다음에 또 뵙겠습니다.`
})
} else {
res.status(404).json({
message: "회원 정보가 없습니다."
})
}
})
'데브코스' 카테고리의 다른 글
[5주차 - DAY2] REST API 개발 실습(2) (1) | 2024.03.26 |
---|---|
[5주차 - DAY1] REST API 개발 실습(1) (0) | 2024.03.25 |
[4주차 복습 발표] API 설계 실습 (0) | 2024.03.21 |
[4주차 - DAY4] Node.js 및 Express.js를 사용한 서버 개발 실습(2) (0) | 2024.03.21 |
[4주차 - DAY3] Node.js 및 Express.js를 사용한 서버 개발 실습(1) (0) | 2024.03.20 |