❄️jwt 검증하는 ensureAuthorization 함수를 모듈로 빼서 관리하기
utils 폴더로 따로 빼주고 파일을 만들어주었다❗
jwtUtils.js
❄️jwt 모듈을 적용한 코드
OrderController.js
BookController.js
지금의 jwt코드에서는 모듈내에서 err가 나면 response를 바로 보내주는 방식으로 구현되어있으므로,
authoriztion이 있을때 id값을 user_id에 넣고, qeury문과 params도 있을때에만 넣어주게
삼항연산자를 사용하여 코드를 구현했다❗
Headers가 없을 때 (비로그인)
Headers가 있을 때(로그인)
전체 도서 조회시 현재 페이지와 총 도서의 수를 response로 보내주기
✨SQL_CALC_FOUND_ROWS
코드 실행으로 COUNT(*)과 다르지 않지만
COUNT(*)가 테이블의 SELECT를 한 번 더 해야하지만
SQL_CALC_FOUND_ROWS는 한 번으로 가능하다
하지만 데이터가 많아질수록 성능 저하의 우려가 있다.
추가적으로 MySQL 8.0 부터는 더 이상 권장되지 않는 기능이라고 한다.
결론: COUNT(*)를 사용하는것이 더 좋다❗
SELECT SQL_CALC_FOUND_ROWS * FROM books;
SELECT found_rows();
✨API 다시 정리하기
도서API
1. 전체 도서 조회
// 이미지 경로, 조회시 아이템 8개씩 보여주기
// 카테고리 id 어떻게 알고 보내줄까?
Method | GET |
URI | /books?limit={page 당 도서 수}¤tPage={현재 page} |
HTTP status code | 성공 200 |
Request Body | |
Response Body | { book: [ { "book_id" : "도서 id", "title" : "도서명", "category" : "도서 카테고리", "summary" : "요약 설명", "author" : "작가명", "price" : 가격, "likes" : 좋아요 수, "pubDate" : "출간일" }, { "book_id" : "도서 id", "title" : "도서명", "category" : "도서 카테고리", "summary" : "요약 설명", "author" : "작가명", "price" : 가격, "likes" : 좋아요 수, "pubDate" : "출간일" }, ... ], pagination: { "currentPage": 현재 페이지, "totalBooks": 총 도서 수 } } |
2. 개별 도서 조회
// 이미지 경로
Method | GET |
URI | /books/:{bookId} |
HTTP status code | 성공 200 |
Request Body | |
Response Body | { "book_id" : "도서 id", "title" : "도서명", "category" : "도서 카테고리", "format" : "포맷", "isbn" : "isbn", "summary" : "요약 설명", "description" : "상세 설명", "author" : "작가명", "pages" : 쪽 수, "index" : "목차", "price" : 가격, "likes" : 좋아요 수, "liked" : boolean, "pubDate" : "출간일" } |
3. 카테고리별 도서 목록 조회
-new: true=> 신간조회(기준: 출간일 30일 이내)
=>출간일을 설정하면 sql에서 30이내인 것을 계산해 줄 수 있다.
// 이미지 경로, 조회시 아이템 8개씩 보여주기
// 카테고리 id 어떻게 알고 보내줄까?
=>id는 숫자로 사용하고 카테고리 테이블을 생성해서 각 숫자별로 장르를 설정해놓는다.
Method | GET |
URI | /books?category={categoryId}&new={boolean} |
HTTP status code | 성공 200 |
Request Body | |
Response Body | [ { "book_id" : "도서 id", "title" : "도서명", "category" : "도서 카테고리", "summary" : "요약 설명", "author" : "작가명", "price" : 가격, "likes" : 좋아요 수 , "pubDate" : "출간일" }, { "book_id" : "도서 id", "title" : "도서명", "category" : "도서 카테고리", "summary" : "요약 설명", "author" : "작가명", "price" : 가격, "likes" : 좋아요 수 , "pubDate" : "출간일" }, ... ] |
장바구니 API
1. 장바구니 담기
Method | POST |
URI | /cart |
HTTP status code | 성공 201 |
Request Headers | Authorization - jwt token |
Request Body | { "book_id" : "도서 id", "count" : 수량 } |
Response Body |
2. 장바구니 조회
Method | GET |
URI | /cart |
HTTP status code | 성공 200 |
Request Headers | Authorization - jwt token |
Request Body | |
Response Body | [ { "cartItem_id" : 장바구니 도서 id, "book_id" : 도서 id, "title" : "도서명", "category" : "도서 카테고리", "summary" : "요약 설명", "count" : 수량 "price" : 가격, }, { "cartItem_id" : 장바구니 도서 id, "book_id" : 도서 id, "title" : "도서명", "category" : "도서 카테고리", "summary" : "요약 설명", "count" : 수량 "price" : 가격, }, ... ] |
3. 장바구니 도서 삭제
Method | DELETE |
URI | /cart/:{bookId} |
HTTP status code | 성공 200 |
Request Headers | Authorization - jwt token |
Request Body | |
Response Body |
4. 장바구니에서 선택한 주문 '예상' 상품 목록 조회
Method | GET |
URI | /cart/:{bookId} |
HTTP status code | 성공 200 |
Request Headers | Authorization - jwt token |
Request Body | ["cartItem_id", "cartItem_id", ...] |
Response Body | [ { "cartItem_id" : 장바구니 도서 id, "book_id" : "도서 id", "title" : "도서명", "category" : "도서 카테고리", "summary" : "요약 설명", "count" : 수량 "price" : 가격, }, { "cartItem_id" : 장바구니 도서 id, "book_id" : "도서 id", "title" : "도서명", "category" : "도서 카테고리", "summary" : "요약 설명", "count" : 수량 "price" : 가격, }, ... ] |
결제(주문) API
1. 결제하기
= 주문하기 = 주문등록 = 데이터베이스 주문 insert = 장바구니에서 주문된 상품은 delete
Method | POST |
URI | /orders |
HTTP status code | 성공 200 |
Request Headers | Authorization - jwt token |
Request Body | { "items" : [ { "cartItem_id" : 장바구니 도서 id, "book_id" : 도서 id, "bookTitle" : "대표 책 제목", "count" : 수량 }, { "cartItem_id" : 장바구니 도서 id, "book_id" : 도서 id, "bookTitle" : "대표 책 제목", "count" : 수량 }, ... ], "delivery" : { "address" : "주소", "receiver" : "받는 사람", "contact" : "010-0000-0000" }, "totalPrice" : 총 금액, "totalCount" : "총 수량" } |
Response Body |
2. 결제목록(내역) 조회
Method | GET |
URI | /orders |
HTTP status code | 성공 200 |
Request Headers | Authorization - jwt token |
Request Body | |
Response Body | [ { "orders_id" : 주문 id, "create_at" : "주문일자", "delivery" : { "address" : "주소", "veceiver" : "받는 사람", "contact" : "전화번호" }, "bookTitle" : "대표 책 제목", "totalPrice" : "총 금액", "totalCount" : "총 수량" ] |
3. 주문 상세 상품 조회
Method | GET |
URI | /orders/:{orderId} |
HTTP status code | 성공 200 |
Request Headers | Authorization - jwt token |
Request Body | |
Response Body | [ { "book_id" : 도서 id, "bookTitle" : "대표 책 제목", "author" : "작가명", "price" : 가격, "count" : 수량 }, { "book_id" : 도서 id, "bookTitle" : "대표 책 제목", "author" : "작가명", "price" : 가격, "count" : 수량 }, ... ] |
🗝️코드 퀄리티를 올려보자
- 중복코드 => 모듈화
ex) UserController.js => User (데이터모듈 = Model) - CRUD
DB 모듈: MySQL => 몽구스, 시퀄라이즈
- 패키지구조
- Router :경로(URI, URL)와 HTTP method로 요청에 따른 경로를 찾아주는 역할
- Controller
- Service
- Model : 데이터베이스와 소통
- 예외처리 (try...catch)
- 유효성 검사
- jwt
- 로그인 시 access token(30m), refresh token(24h)
- access token 인증
- refresh token 연장
- 랜던 데이터(외부) API를 활용해서 isbn 샘플 데이터 채워보기
❄️랜덤 데이터 API 사용해보기
개요
- 랜덤 데이터를 생성해주는 API (외부 API)를 기반으로 가짜 사용자 정보 생성 API
내용
- 랜덤 데이터 생성 API (가짜 사용자, 상품, 전화번호 등)
- 가짜 사용자 정보를 생성하는 Express 웝/앱 API
랜덤 데이터 생성 API
- faker
- mokaroo
❄️faker 사용해보기
yarn add -D @faker-js/faker
npm의 --save-dev 혹은 yanr의 -D나 -dev는 개발의존성 설치로
개발단계에서만 사용하고 배포 후에는 사용하지 않을 것임을 나타내는 것이고
배포 후에도 사용할 것이라면 이 부분은 빼고 외부모듈이름만 적어서 설치하면 된다.