지난 시간에는 JWT를 활용해 API를 수정해 보았어요.
이번 시간에는 인가(Authorization) 로직을 모듈화 하고 나머지 API들에도 적용해 볼게요. 추가로 API 설계 문서와 실제 구현 코드를 비교하면서 어색한 네이밍이나 부족한 부분도 함께 수정해 보려고 해요.
테이블의 전체 데이터 개수(행 수)를 구하기 위해서는 크게 두 가지 방법이 있어요.
-- 1번 방법
SELECT count(*) FROM table;
-- 2번 방법
SELECT SQL_CALC_FOUND_ROWS * FROM table;
SELECT found_rows();
두 가지 모두 전체 행 수를 구할 수 있는 방법이지만, MySQL 8.0 버전부터는 2번 방법이 권장되지 않는다고 해요. 따라서 1번 방법인 count() 를 사용하는 것을 추천해요.
API 중에서 로그인한 상태와 안 한 상태를 모두 하나의 요청에서 처리해야 하는 경우가 있어요. 이때 로직을 구현하는 방식에는 크게 두 가지가 있어요.
request )의 authorization 헤더를 확인하고, 비어있으면 빈 토큰을 반환하는 방법저는 이 중에서 1번 방법으로 구현했어요. 새로운 에러를 만들어서 던지면 예외 처리 코드가 너무 복잡해지고, 비슷한 코드의 중복이 발생한다고 느꼈거든요.
지난 시간에 구현했던 기능들에 새롭게 만든 인가 모듈을 적용해 주었어요.
공통 로직을 모듈화해서 깔끔하게 분리했기 때문에, 기능적인 결과는 이전과 똑같이 잘 동작해요.
1. 개별 도서 조회 (로그인 O / 로그인 X)
전체 도서 목록을 볼 때는 인가가 필요 없지만, 개별 도서를 상세 조회할 때는 사용자가 이 책에 '좋아요'를 눌렀는지 여부를 확인하기 위해 인가 과정이 필요해요.
로그인을 하지 않은 사용자도 책의 상세 정보 자체는 볼 수 있어야 하므로, 로그인을 한 경우에만 좋아요 여부( is_like )를 판별해서 응답( response )에 담아 보내주도록 수정했어요.
2. 전체 도서 목록 조회 (페이지네이션 추가)
단순히 책 목록 데이터만 보내는 것이 아니라, 프론트엔드 화면 하단에 페이지 버튼을 그려주기 위해 현재 페이지와 전체 데이터 수 등 페이지네이션 정보를 추가로 보내주도록 수정했어요.
주문하기와 주문 목록 조회, 상세 조회 API 등에도 새롭게 만든 인가 모듈을 적용시켜 주었어요. 테스트해 보니 모두 정상적으로 동작하는 것을 확인했어요!
마지막으로 API 설계 문서와 실제 구현 코드를 비교하면서 변수 이름들을 통일하는 작업을 진행했어요.
저는 클라이언트의 요청( request )으로 들어오는 데이터는 카멜 케이스(camelCase)로, 서버에서 나가는 응답( response ) 데이터는 스네이크 케이스(snake_case)로 작성했는데, 사실 이런건 무조건 하나로 통일해야하는데, 인강 따라 하면서 언제 바꾸지 하고 있었어요.
하나로 통일해줬어요.
랜덤 데이터 생성하는 api를 만들어봤어요.
fakerjs
mockaroo
랜덤 데이터를 생성하는 데에는 이러한 라이브러리들이 있어요.
const express = require("express");
const app = express();
const { faker, fa } = require("@faker-js/faker");
app.get("/fake/users", (req, res) => {
const { num } = req.query;
const users = [];
for (let i = 0; i < parseInt(num); i++) {
users.push({
email: faker.internet.email(),
password: faker.internet.password(),
fullName: faker.person.fullName(),
ph_num: faker.helpers.fromRegExp(/010-[0-9]{4}-[0-9]{4}/),
});
}
return res.status(200).json(users);
});
app.listen(3002);