๐ŸŽฏ ๋ชจ๋“  API๋ฅผ ์ตœ์ข…์ ์œผ๋กœ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ“™ Today I Learned

ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

MVC ํŒจํ„ด์„ ํ™œ์šฉํ•˜์—ฌ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•˜๋„๋ก ๊ตฌ์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๐Ÿ“ฆBOOK-SHOP/  
โ”œโ”€โ”€ ๐Ÿ“‚controller/          #  ์š”์ฒญ์„ ๋ฐ›์•„ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ํ˜ธ์ถœ  
โ”‚   โ”œโ”€โ”€ BookController.js  
โ”‚   โ”œโ”€โ”€ CartController.js  
โ”‚   โ”œโ”€โ”€ CategoryController.js  
โ”‚   โ”œโ”€โ”€ LikeController.js  
โ”‚   โ”œโ”€โ”€ OrderController.js  
โ”‚   โ””โ”€โ”€ UserController.js  
โ”‚  
โ”œโ”€โ”€ ๐Ÿ“‚service/             #  ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ฒ˜๋ฆฌ  
โ”‚   โ”œโ”€โ”€ BookService.js  
โ”‚   โ”œโ”€โ”€ CartService.js  
โ”‚   โ”œโ”€โ”€ CategoryService.js  
โ”‚   โ”œโ”€โ”€ LikeService.js  
โ”‚   โ”œโ”€โ”€ OrderService.js  
โ”‚   โ””โ”€โ”€ UserService.js  
โ”‚  
โ”œโ”€โ”€ ๐Ÿ“‚model/               #  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ชจ๋ธ ์ •์˜  
โ”‚   โ”œโ”€โ”€ Book.js  
โ”‚   โ”œโ”€โ”€ Cart.js  
โ”‚   โ”œโ”€โ”€ Category.js  
โ”‚   โ”œโ”€โ”€ Like.js  
โ”‚   โ”œโ”€โ”€ Order.js  
โ”‚   โ””โ”€โ”€ User.js  
โ”‚  
โ”œโ”€โ”€ ๐Ÿ“‚routes/              #  ๋ผ์šฐํ„ฐ ์„ค์ •  
โ”‚   โ”œโ”€โ”€ books.js  
โ”‚   โ”œโ”€โ”€ carts.js  
โ”‚   โ”œโ”€โ”€ categories.js  
โ”‚   โ”œโ”€โ”€ likes.js  
โ”‚   โ”œโ”€โ”€ orders.js  
โ”‚   โ””โ”€โ”€ users.js  
โ”‚  
โ”œโ”€โ”€๐Ÿ“‚validation/           #  ์š”์ฒญ ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ  
โ”‚   โ”œโ”€โ”€ bookValidation.js  
โ”‚   โ”œโ”€โ”€ cartValidation.js  
โ”‚   โ”œโ”€โ”€ categoryValidation.js  
โ”‚   โ”œโ”€โ”€ likeValidation.js  
โ”‚   โ”œโ”€โ”€ orderValidation.js  
โ”‚   โ””โ”€โ”€ userValidation.js  
โ”‚  
โ”‚  
โ”œโ”€โ”€ .env                 #  ํ™˜๊ฒฝ ๋ณ€์ˆ˜ 
โ”œโ”€โ”€ app.js               #  Express ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ดˆ๊ธฐํ™”  
โ”œโ”€โ”€ auth.js              #  ์ธ์ฆ ๊ด€๋ จ ๋กœ์ง  
โ”œโ”€โ”€ mariadb.js           #  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ  
โ”œโ”€โ”€ package.json         #  ํ”„๋กœ์ ํŠธ ์˜์กด์„ฑ  
โ””โ”€โ”€ package-lock.json    #  ํŒจํ‚ค์ง€ ๋ฒ„์ „ ๊ด€๋ฆฌ  

MVC ํŒจํ„ด

์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ๋ชจ๋ธ(Model), ๋ทฐ(View), ์ปจํŠธ๋กค๋Ÿฌ(Controller)๋กœ ๋‚˜๋ˆ„์–ด ๊ตฌ์กฐํ™”ํ•˜๋Š” ๋””์ž์ธ ํŒจํ„ด์ž…๋‹ˆ๋‹ค.

  • Model : ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ๊ด€๋ จ๋œ ๋กœ์ง์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.

  • View : ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์ด๋Š” UI๋ฅผ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค. (API ํ”„๋กœ์ ํŠธ์ด๋ฏ€๋กœ ๋ทฐ๊ฐ€ ๋”ฐ๋กœ ์—†์Œ)

  • Controller : ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ๋ฐ›์•„ ๋ชจ๋ธ๊ณผ ๋ทฐ๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ์—ญํ• .




MYSQL ํŽ˜์ด์ง€๋„ค์ด์…˜ ๊ตฌํ˜„

1๏ธโƒฃ LIMIT & OFFSET ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

SELECT * FROM Bookshop.books LIMIT 4 OFFSET 0;
SELECT count(*) FROM Bookshop.books;

2๏ธโƒฃ SQL_CALC_FOUND_ROWS๋ฅผ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

SELECT SQL_CALC_FOUND_ROWS * FROM Bookshop.books LIMIT 4 OFFSET 0;
SELECT found_rows();

๐Ÿ‘Ž ํ•˜์ง€๋งŒ ์„ฑ๋Šฅ์ด ๋–จ์–ด์ง€๋ฏ€๋กœ ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ์—์„œ๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.




ํšŒ์› API

๐Ÿ‘‰ ์ˆ˜์ •ํ•œ ๋ถ€๋ถ„์€ ์ฃผํ™ฉ์ƒ‰ ๊ธ€์”จ๋กœ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

ํšŒ์› ๊ฐ€์ž…

  • Method : POST

  • URL : /users/join

  • HTTP Status Code : 201 Created

  • Request Body

  {
    "email": "์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ์ด๋ฉ”์ผ",
    "password" : "์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๋น„๋ฐ€๋ฒˆํ˜ธ"
  }
  • Response Body : x

๋กœ๊ทธ์ธ

  • Method : POST

  • URL : /users/login

  • HTTP Status Code : 200 Ok

  • Request Body

  {
    "email": "์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ์ด๋ฉ”์ผ",
    "password" : "์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๋น„๋ฐ€๋ฒˆํ˜ธ"
  }
  • Response Cookie : JWT Token

๋น„๋ฐ€๋ฒˆํ˜ธ ์ดˆ๊ธฐํ™” ์š”์ฒญ

  • Method : POST

  • URL :/users/rest

  • HTTP Status Code : 200 Ok

  • Request Body

  {
    "email": "์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ์ด๋ฉ”์ผ"
  }
  • Response Body
  {
    "email": "์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ์ด๋ฉ”์ผ"
  }

๋น„๋ฐ€๋ฒˆํ˜ธ ์ดˆ๊ธฐํ™”

  • Method : PUT

  • URL : /users/rest

  • HTTP Status Code : 200 Ok

  • Request Body

  {
    "email": "์ด์ „ ํŽ˜์ด์ง€์—์„œ ์ž…๋ ฅํ•œ ์ด๋ฉ”์ผ",
    "password" : "์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๋น„๋ฐ€๋ฒˆํ˜ธ"
  }
  • Response Body : x



์ข‹์•„์š” API


์ˆ˜์ •ํ•œ ๋ถ€๋ถ„์€ ์ฃผํ™ฉ์ƒ‰ ๊ธ€์”จ๋กœ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

์ข‹์•„์š” ์ถ”๊ฐ€

  • Method : POST

  • URL : /likes/:bookId

  • HTTP Status Code : 200 Ok

  • Request Headers : 'Authorization' : JWT Token

  • Response Body : x


์ข‹์•„์š” ์ทจ์†Œ

  • Method : DELETE

  • URL : /likes/:bookId

  • HTTP Status Code : 200 Ok

  • Request Headers : 'Authorization' : JWT Token

  • Response Body : x




๋„์„œ API

๐Ÿ‘‰ ์ˆ˜์ •ํ•œ ๋ถ€๋ถ„์€ ์ฃผํ™ฉ์ƒ‰ ๊ธ€์”จ๋กœ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

์ „์ฒด ๋„์„œ ์กฐํšŒ

  • Method : GET

  • URL :/books?limit=๊ฐœ์ˆ˜&currentPage=ํŽ˜์ด์ง€๋ฒˆํ˜ธ

  • HTTP Status Code : 200 Ok

  • Response Body :

{
  "books" : [
    {
      "id" : ๋„์„œ id,
      "title": "๋„์„œ ์ œ๋ชฉ",
      "img" : ์ด๋ฏธ์ง€ id,
      "summary" : "์š”์•ฝ ์„ค๋ช…",
      "author" : "๋„์„œ ์ž‘๊ฐ€",
      "price" : ๊ฐ€๊ฒฉ,
      "likes" : ์ข‹์•„์š” ์ˆ˜,
      "pubDate" : "์ถœ๊ฐ„ ๋‚ ์งœ"
    },
    {
      "id" : ๋„์„œ id,
      "title": "๋„์„œ ์ œ๋ชฉ",
      "img" : ์ด๋ฏธ์ง€ id,
      "summary" : "์š”์•ฝ ์„ค๋ช…",
      "author" : "๋„์„œ ์ž‘๊ฐ€",
      "price" : ๊ฐ€๊ฒฉ,
      "likes" : ์ข‹์•„์š” ์ˆ˜,
      "pubDate" : "์ถœ๊ฐ„ ๋‚ ์งœ"
    },
    ...
  ],
  "pagination": {
  	"currentPage": ํ˜„์žฌ ํŽ˜์ด์ง€,
    "totalCount": ์ด ๋„์„œ ์ˆ˜
  }
}

๊ฐœ๋ณ„ ๋„์„œ ์กฐํšŒ

  • Method : GET

  • URL : /books/:id

  • HTTP Status Code : 200 Ok

  • Request Headers : 'Authorization' : JWT Token

  • Response Body :

{
  "id" : ๋„์„œ id,
  "title": "๋„์„œ ์ œ๋ชฉ",
  "img" : ์ด๋ฏธ์ง€ id,
  "categoryName" : "์นดํ…Œ๊ณ ๋ฆฌ",
  "form" : "ํฌ๋งท",
  "isbn" : "isbn",  
  "summary" : "์š”์•ฝ ์„ค๋ช…",
  "detail" : "์ž์„ธํ•œ ์„ค๋ช…",
  "author" : "๋„์„œ ์ž‘๊ฐ€",
  "pages" : ์ชฝ ์ˆ˜,
  "contents" : "๋ชฉ์ฐจ",
  "price" : ๊ฐ€๊ฒฉ,
  "likes" : ์ข‹์•„์š” ์ˆ˜,
  "liked" : boolean, (๋กœ๊ทธ์ธ์ธ ์ƒํƒœ์—๋งŒ ๋ณด๋‚ด์คŒ)
  "pubDate" : "์ถœ๊ฐ„ ๋‚ ์งœ"
}

์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ์‹ ๊ฐ„ ๋„์„œ ์กฐํšŒ

  • Method : GET

  • URL : /books?categoryId=:categoryId&news={boolean}

  • HTTP Status Code : 200 Ok

  • Request Body : x

  • Response Body :

[
  {
    "id" : ๋„์„œ id,
    "title": "๋„์„œ ์ œ๋ชฉ",
    "img" : ์ด๋ฏธ์ง€ id,
    "summary" : "์š”์•ฝ ์„ค๋ช…",
    "author" : "๋„์„œ ์ž‘๊ฐ€",
    "price" : ๊ฐ€๊ฒฉ,
    "likes" : ์ข‹์•„์š” ์ˆ˜,
    "pubDate" : "์ถœ๊ฐ„ ๋‚ ์งœ"
  },
  {
    "id" : ๋„์„œ id,
    "title": "๋„์„œ ์ œ๋ชฉ",
    "img" : ์ด๋ฏธ์ง€ id,
    "summary" : "์š”์•ฝ ์„ค๋ช…",
    "author" : "๋„์„œ ์ž‘๊ฐ€",
    "price" : ๊ฐ€๊ฒฉ,
    "likes" : ์ข‹์•„์š” ์ˆ˜,
    "pubDate" : "์ถœ๊ฐ„ ๋‚ ์งœ"
  },
  ...
]
  • ์ฐธ๊ณ ์‚ฌํ•ญ : news๊ฐ€ true์ผ ๋•Œ ์‹ ๊ฐ„ ์กฐํšŒ ๊ธฐ์ค€์€ ์ถœ๊ฐ„์ผ๋กœ๋ถ€ํ„ฐ 1๋‹ฌ ์ด๋‚ด



์žฅ๋ฐ”๊ตฌ๋‹ˆ API

์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋‹ด๊ธฐ

  • Method : POST

  • URL : /carts

  • HTTP Status Code : 200 Ok

  • Request Headers : 'Authorization' : JWT Token

  • Request Body

  {
    "bookId" : ๋„์„œ id,
    "quantity" : ์ˆ˜๋Ÿ‰,
  }
  • Response Body : x

์žฅ๋ฐ”๊ตฌ๋‹ˆ ์กฐํšŒ / ์„ ํƒ ์ƒํ’ˆ ์กฐํšŒ(์ฃผ๋ฌธ์„œ ์ž‘์„ฑ)

  • Method : GET

  • URL : /carts

  • HTTP Status Code : 200 Ok

  • Request Headers : 'Authorization' : JWT Token

  • Request Body :

{
   "selected" : [cartItemId, cartItemId ...]
}
  • Response Body
 [
  { 
    "id" : ์žฅ๋ฐ”๊ตฌ๋‹ˆ id,
    "bookId" : ๋„์„œ id,
    "title" : "๋„์„œ ์ œ๋ชฉ",
    "summary" : "์š”์•ฝ ์„ค๋ช…",
    "quantity" : ์ˆ˜๋Ÿ‰,
    "price" : ๊ฐ€๊ฒฉ
  },
  {
    "id" : ์žฅ๋ฐ”๊ตฌ๋‹ˆ id,
    "bookId" : ๋„์„œ id,
    "title" : "๋„์„œ ์ œ๋ชฉ",
    "summary" : "์š”์•ฝ ์„ค๋ช…",
    "quantity" : ์ˆ˜๋Ÿ‰,
    "price" : ๊ฐ€๊ฒฉ
  },
 ]

์žฅ๋ฐ”๊ตฌ๋‹ˆ ์‚ญ์ œ

  • Method : DELETE

  • URL : /carts/:cartItemId

  • HTTP Status Code : 200 Ok

  • Request Headers : 'Authorization' : JWT Token

  • Request Body : x

  • Response Body : x




์ฃผ๋ฌธ(๊ฒฐ์ œ) API

์ฃผ๋ฌธํ•˜๊ธฐ

  • Method : POST

  • URL : /orders

  • HTTP Status Code : 200 Ok

  • Request Headers : 'Authorization' : JWT Token

  • Request Body

{
  "items": [ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋„์„œ id, ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋„์„œ id, ...],
  "delivery" : {
    	"address" : "์ฃผ์†Œ",
    	"receiver" : "์ด๋ฆ„",
    	"contact" : "์ „ํ™”๋ฒˆํ˜ธ"
  },
  "totalQuantity" : ์ด ์ˆ˜๋Ÿ‰,
  "totalPrice" : ์ด ๊ธˆ์•ก,
  "firstbookTitle" : "๋Œ€ํ‘œ ๋„์„œ ์ œ๋ชฉ"
}
  • Response Body : x

์ฃผ๋ฌธ ๋ชฉ๋ก ์กฐํšŒ

  • Method : GET

  • URL : /orders

  • HTTP Status Code : 200 Ok

  • Request Headers : 'Authorization' : JWT Token

  • Response Body :
[
  {
    "orderId" : ์ฃผ๋ฌธ id,
  	"createdAt" : "์ฃผ๋ฌธ์ผ์ž",
    "address" : "์ฃผ์†Œ",
    "receiver" : "์ด๋ฆ„",
    "contact" : "์ „ํ™”๋ฒˆํ˜ธ",
  	"bookTitle" : "๋Œ€ํ‘œ ์ฑ… ์ œ๋ชฉ",
    "totalQuantity" : ์ด ์ˆ˜๋Ÿ‰,
  	"totalPrice" : ๊ฒฐ์ œ ๊ธˆ์•ก,

  },
  {
    "orderId" : ์ฃผ๋ฌธ id,
  	"createdAt" : "์ฃผ๋ฌธ์ผ์ž",
    "address" : "์ฃผ์†Œ",
    "receiver" : "์ด๋ฆ„",
    "contact" : "์ „ํ™”๋ฒˆํ˜ธ",
  	"bookTitle" : "๋Œ€ํ‘œ ์ฑ… ์ œ๋ชฉ",
    "totalQuantity" : ์ด ์ˆ˜๋Ÿ‰,
  	"totalPrice" : ๊ฒฐ์ œ ๊ธˆ์•ก,
  },
  ...
]

์ฃผ๋ฌธ ์ƒ์„ธ ์กฐํšŒ

  • Method : GET

  • URL : /orders/:id

  • HTTP Status Code : 200 Ok

  • Request Headers : 'Authorization' : JWT Token

  • Response Body :
[
  {
    "bookId" : ๋„์„œ id,
    "title" : "๋„์„œ ์ œ๋ชฉ",
    "author" : "์ž‘๊ฐ€",
    "price" : ๊ฐ€๊ฒฉ,
    "quantity" : ์ˆ˜๋Ÿ‰
  },
  {
    "bookId" : ๋„์„œ id,
    "title" : "๋„์„œ ์ œ๋ชฉ",
    "author" : "์ž‘๊ฐ€",
    "price" : ๊ฐ€๊ฒฉ,
    "quantity" : ์ˆ˜๋Ÿ‰
  },
  ...
]



โœ๏ธ ํ•œ ์ค„ ํšŒ๊ณ 

๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ ๊ฐ•์˜๊ฐ€ ๋๋‚ฌ๋‹ค๋Š” ๊ฒŒ ์‹ค๊ฐ์ด ์•ˆ ๋‚˜๊ณ , MVC ํŒจํ„ด์„ ํ™œ์šฉํ•ด์„œ ์ฝ”๋“œ๋ฅผ ์ •๋ฆฌํ•˜๋Š” ๊ณผ์ œ๋ฅผ ๋…ํ•™ํ•ด์„œ ์ž˜ ๋งˆ๋ฌด๋ฆฌํ•ด์•ผ๊ฒ ์Šต๋‹ˆ๋‹ค!!

profile
๐ŸŒฑ๊ฐœ๋ฐœ ๊ธฐ๋ก์žฅ

0๊ฐœ์˜ ๋Œ“๊ธ€