
오늘은 어제 다 못한 로그인 api를 마저 구현해봤어요.
강의에서는 hasUserId 를 var로 전역변수화해서 예외처리를 하는데, 저는 전역변수 사용을 최소화하고 early return을 사용하는 게 가독성 측면에서 더 좋다고 생각했어요.
안 그래도 전역변수 때문에 if문에서 오류가 나는 것을 보고, var이나 {}으로 if문을 처리할 때 정말 조심해야 겠다고 생각했어요.
Object의 경우 값이 없고 비어 있는 상태를 확인하기 위해서는 여러 방법들이 있습니다.

이중 Object.keys() 를 활용해봤어요.
비어있는 obj1는 배열의 length가 0으로 나오니, 이것으로 검증할 수 있겠어요.

역시 예상대로 각각 true 와 false 가 나온 것을 확인할 수 있었어요.
문자열도 객체기 때문에 "one" 과 "" 를 똑같이 해도 각각 true 와 false 가 나오는 것을 볼 수 있었어요.
아예 이 과정을 함수로 isEmpty() 로도 만들 수 있습니다.
const user = Array.from(db.values()).find(user => user.email === email);
기존 제가 db에서 유저를 찾는 코드에요.
find를 사용하다보니 계속 배열을 만들어야하고, O(n)의 시간복잡도를 가져 이것을 개선하고 싶었어요.
개선한 코드는 이렇습니다.
let user;
// 배열 생성 없이 하나씩 꺼내서 검사
for ( const u of db.values()) {
if (u.email === email) {
user = u;
// 찾으면 중단
break;
}
}
들여쓰기가 두 번 있는 건 가독성 측면에서 마음에 들지 않지만, 성능적으로 배열을 생성하지 않으니 메모리 부담이 덜하다고 생각했어요.
app.post('/login', (req,res) => {
const { email, password } = req.body;
// email로 db에 있는 유저 조회하기
let user;
// 배열 생성 없이 하나씩 꺼내서 검사
for ( const u of db.values()) {
if (u.email === email) {
user = u;
// 찾으면 중단
break;
}
}
if (!user) return res.status(401).json({ "message": "Invalid Email" });
// password도 맞는지 비교
if (user.password !== password) return res.status(401).json({"message": "Invalid Password"});
res.json(user);
});
최종적인 로그인 코드에요. 저는 로그인 실패시 401(UNAUTHORIZED) 상태코드를 사용했어요.
모두 prefix가 channels라서 app.route() 를 사용했어요.
고민이 됐던 건 채널 전체 조회시 빈 객체가 온다면 200, 204, 404 중에 어떤 것을 사용할까였어요.
강의에서는 404를 쓰는데, 404는 클라이언트 입장에서 try catch에서 catch문에 걸리기 때문에 404는 가장 아니라고 생각했어요.
404는 /channels/:id 처럼 특정한 리소스 요청에 실패했을 때 주는 게 맞다고 생각했어요.
그리고 [] 빈 배열에 200을 담아 주는 게 요청이 성공했다는 뜻을 주니까 맞다고 생각했어요.
코드가 길어서 다 올리기 보다 제가 patch로 수정 구현한 걸 여기에 올리고 싶었어요.
.patch((req, res) => {
const id = parseInt(req.params.id);
let channel = db.get(id);
if (!channel) return res.status(404).json({"message": `${id} Channel Not Found`});
const oldChannelTitle = channel.channelTitle;
const newChannel = {
...channel,
...req.body
};
db.set(id, newChannel);
res.json({
"message": `${oldChannelTitle}이 ${newChannel.channelTitle}로 변경되었습니다.`,
})
})
스프레드 연산자로 새로운 채널을 만들어 db에 저장하도록 구현했어요.

GET /channels

POST /channels

PATCH /channels/:id

DELETE /channels/:id