프로젝트 4-1 ~ 4-7(도서 & 카테고리 API, queryString, picsum)

Develop Kim·2024년 10월 3일

programmers

목록 보기
23/40

프로젝트: Node.js 기반의 REST API 구현

1 설계를 직접 해보자

1-1 ~ 1-6(API 설계)

1-7 ~ 1-11(ERD 설계)

2 프로젝트 구현 시작

1-12 ~ 2-5(API 설계 점검, 기본 세팅(모듈화, postman, diagram, workbranch))

3 회원 API(feat. 비밀번호 암호화)

3-1 ~ 3-7(비밀번호 암호화)

4 도서 API(feat. 나에게 페이징이란?)

4-1 도서 테이블 생성

1️⃣ 테이블을 설계한대로 만들어보자

  • 아래와 같이 설계를 참고하여 테이블을 만들었다.

2️⃣ (쿠키영상) 잠깐! 컬럼 이름 변경 필요합니다!

  • SQL에는 예약어가 존재한다!
    • 모든 곳에서는 예약어를 쓰면 좋지 않기 때문에 예약어로 사용이 된다면 피해줘야 함
  • 컬럼에서 예약어를 사용하면 꼬일 수 있기 때문에 컬럼명을 수정해준다.
    • formet -> form, index -> contents



4-2 BookController 떼어내기

1️⃣ books와 컨트롤러를 분리

const express = require("express");
const router = express.Router();
const conn = require('../mariadb'); // db 모듈
const {
  allBooks,
  bookDetail,
  booksByCategory
} = require('../controller/BookController'); // 컨트롤러 불러옴

router.use(express.json()); // POST를 사용하면 값을 json형태로 받아오기 때문에 추가

// 도서 전체 조회
router.get('/', allBooks);

// 도서 개별 조회
router.get('/:id', bookDetail);

// 카테고리별 도서 목록 조회
router.get('/', booksByCategory);

module.exports = router;
const {StatusCodes} = require('http-status-codes'); // 상태 모듈
const conn = require('../mariadb'); // db 모듈

// 도서 전체 조회
const allBooks = (req,res) => {
  res.json('도서 전체 조회');
}

// 도서 개별 조회
const bookDetail = (req,res) => {
  res.json('도서 개별 조회');
};

// 카테고리별 도서 목록 조회
const booksByCategory = (req,res) => {
  res.json('카테고리별 도서 목록 조회');
};

module.exports = {
  allBooks,
  bookDetail,
  booksByCategory
};



4-3 도서 전체 조회, 상세 도서 조회

1️⃣ 도서 전체조회

  • 잘 출력 됨
// 도서 전체 조회
const allBooks = (req,res) => {
  // 요약된 전체 도서 리스트
  let sql = "SELECT * FROM books";
  conn.query(sql, (err, results) => {
      if(err) {
        console.log(err);
        return res.status(StatusCodes.BAD_REQUEST).end // BAD REQUEST
      }
      return res.status(StatusCodes.OK).json(results)
    })
}

2️⃣ 개별 도서 조회

const bookDetail = (req, res) => {
  // URL 경로에서 id를 추출 (req.params는 URL의 경로 매개변수를 나타냄)
  let { id } = req.params; // URL에 포함된 id를 비구조화 할당으로 추출

  // 특정 id의 책 정보를 조회하는 SQL 쿼리문
  let sql = "SELECT * FROM books WHERE id=?";
  
  // 데이터베이스 쿼리 실행
  conn.query(sql, id, (err, results) => {
    // 쿼리 실행 중 에러가 발생한 경우
    if (err) {
      console.log(err); // 에러를 콘솔에 출력
      return res.status(StatusCodes.BAD_REQUEST).end(); // 400 Bad Request로 응답
    }
    
    // 조회된 책 정보가 존재하는 경우
    if (results[0]) {
      return res.status(StatusCodes.OK).json(results[0]); // 첫 번째 결과를 JSON 형식으로 응답
    } else {
      // 책 정보가 없는 경우 (id에 해당하는 책이 존재하지 않을 때)
      return res.status(StatusCodes.NOT_FOUND).end(); // 404 Not Found로 응답
    }
  });
};



4-4 piksum 소개, 이미지 경로 추가

1️⃣ piksum를 이용해보자

  • 가짜 이미지를 불러오는 사이트로 이미지 경로추가하기 쉬움
  • 사용방법은 간단함 url뒤 이미지 id와 그 뒤 이미지 크기를 설정하면 즉시 사용이 가능함

2️⃣ 이미지 경로를 추가해보자

  • 먼저, 데이터 베이스에 이미지 주소를 넣어보자

  • 테이블에는 이미지 번호만 넣어주면 된다.




4-5 카테고리별 도서 목록 조회

1️⃣ 카테고리 목록 조회를 위해 QueryString를 사용해보자

  • 엑셀에서 테이블을 설계한대로
  • 데이터 베이스에도 추가해준다
  • SQL문의 WHERE절로 잘 작동되는 것을 확인할 수 있다.

2️⃣ 카테고리별 도서 조회

const booksByCategory = (req, res) => {
  // 클라이언트가 보낸 쿼리 파라미터에서 category_id를 추출
  let { category_id } = req.query; 

  // 특정 category_id에 속한 도서를 조회하는 SQL 쿼리문
  let sql = "SELECT * FROM books WHERE category_id=?";
  
  // 데이터베이스 쿼리 실행
  conn.query(sql, category_id, (err, results) => {
    // 쿼리 실행 중 에러가 발생한 경우
    if (err) {
      console.log(err); // 에러를 콘솔에 출력
      return res.status(StatusCodes.BAD_REQUEST).end(); // 400 상태 코드 응답
    }

    // 조회된 도서 목록이 존재하는 경우
    if (results.length) {
      return res.status(StatusCodes.OK).json(results); // 전체 도서 목록을 배열로 응답
    } else {
      // 도서 목록이 없는 경우 (해당 카테고리에 도서가 없을 때)
      return res.status(StatusCodes.NOT_FOUND).end(); // 404 상태 코드 응답
    }
  });
};
  • url을 queryString으로 작성하니 잘 작동되는 것을 확인



4-6 카테고리 테이블 생성

1️⃣ 전체도서 조회와 카테고리의 URL이 같아서 에러발생

  • 카테고리가 잘 작동하니 전체도서 조회에서 에러가 난다.
  • 그렇다면 API를 합치는 것이 좋을까? 합치니 잘 작동된다.
// 도서 전체 & 카테고리 조회
const allBooks = (req,res) => {
  let {category_id} = req.query; 

  if(category_id) { // 카테고리 조회
    let sql = "SELECT * FROM books WHERE category_id=?";
    conn.query(sql, category_id,
      (err, results) => {
        if(err) {
          console.log(err);
          return res.status(StatusCodes.BAD_REQUEST).end(); // BAD REQUEST
        }
        if(results.length)
          return res.status(StatusCodes.OK).json(results[0]); // results[0]을 보내면 배열형태가 아니게 됨
        else
          return res.status(StatusCodes.NOT_FOUND).end();
      })
  } else { // 도서 전체조회
  let sql = "SELECT * FROM books";
  conn.query(sql, (err, results) => {
      if(err) {
        console.log(err);
        return res.status(StatusCodes.BAD_REQUEST).end(); // BAD REQUEST
      }
      return res.status(StatusCodes.OK).json(results);
    })
  }
};

2️⃣ 카테고리 테이블 생성

  • 지금은 카테로기 아이디가 숫자로 나오지만, 동화 처럼 장르가 나와줘야 함
  • 테이블을 새로 만들어주자

3️⃣ 카테고리 API 설계

  • 테이블을 추가한 만큼 API도 새롭게 만들어주자

카테고리 전체 조회 API

  • Method : GET
  • URL : /category
  • HTTP status code : 성공 200
  • Request Body :
  • Response Body :
[
	{
    	id : 0,
        name : "동화"
    },
    {
    	id : 1,
        name : "소설"
    },
    ...
]



4-7 카테고리 전체 목록 조회 API 구현

1️⃣ 카테고리 루트 만들기

  • 카테코리는 쿼리스트링이라서 books 루트에 같이 쓰게되면 url이 안 맞을 수 있어서 route를 하나 만들어주자
const express = require("express");
const router = express.Router();
const conn = require('../mariadb'); // db 모듈
const {allCategory} = require('../controller/CategoryController')

router.use(express.json()); // POST를 사용하면 값을 json형태로 받아오기 때문에 추가

// 카테고리 전체 목록 조회
router.get('/', allCategory);

module.exports = router;
const {StatusCodes} = require('http-status-codes'); // 상태 모듈
const conn = require('../mariadb'); // db 모듈

// 카테고리 전체 목록 조회
const allCategory = (req,res) => {

  let sql = "SELECT * FROM category";
  conn.query(sql, (err, results) => {
      if(err) {
        console.log(err);
        return res.status(StatusCodes.BAD_REQUEST).end(); // BAD REQUEST
      }
      return res.status(StatusCodes.OK).json(results);
    })
  };

module.exports = {allCategory}




profile
김개발의 개발여정

0개의 댓글