이번 실습에서는 쇼핑몰 애플리케이션 Cmarket의 데이터베이스를 구축해보고자 한다. 모든 요청은 반드시 데이터베이스를 이용해야 하고, 구현한 Cmarket은 영속적인 데이터를 가질 수 있어야 한다.
사전 준비
CREATE DATABASE cmarket;
mysql -u root -p < server/schema.sql -Dcmarket
mysql -u root -p < server/seed.sql -Dcmarket
Server 실습
app.js
const express = require('express');
const indexRouter = require('./routes');
const cors = require('cors');
const morgan = require('morgan');
const app = express();
const port = 4000;
app.use(
morgan(' :method :url :status :res[content-length] - :response-time ms')
);
app.use(cors());
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use('/', indexRouter);
module.exports = app.listen(port, () => {
console.log(` 🚀 Server is starting on ${port}`);
});
user.js 생성
const router = require('express').Router();
const controller = require('./../controllers');
// users 엔드포인트 뒤에 들어오는 형식이 있기 때문에
// 똑같이 맞춰줘야 컨트롤러로 분기 할 수 있다.
router.get('/:userId/orders', controller.orders.get);
router.post('/:userId/orders', controller.orders.post);
module.exports = router;
Model/index.js
의 items 함수
post: (userId, orders, totalPrice, callback)을 살펴보면, 데이터베이스에 각각 추가해줘야 하는 내용들이 있다. orders.itemId, orders.quantity를 통해 쿼리를 날려줘야 하는데, 여기서 잠깐 데이터베이스 구조를 확인해보면 다음과 같다.
orders테이블에 userId, totalPrice를 추가해줘야 하고, orders의 id(Pk)값을 받아온다. 또한, orders 테이블의 id(PK)를 order_items의 order_id(PK)에 넣어줘야 한다. 즉, 쿼리를 두 번 보내줘야 한다.
controllers/index.js
const models = require('../models');
module.exports = {
items: {
get: (req, res) => {
models.items.get((error, result) => {
if (error) {
res.status(500).send('Internal Server Error');
} else {
res.status(200).json(result);
}
});
},
},
orders: {
get: (req, res) => {
const userId = req.params.userId;
if (!userId) {
return res.status(401).send("Error 400");
}
models.orders.get(userId, (error, result) => {
if (error) {
res.status(500).send('조회 실패');
} else {
res.status(200).json(result);
}
});
},
post: (req, res) => {
const userId = req.params.userId;
const { orders, totalPrice } = req.body;
if( !orders || !totalPrice || !userId ) {
return res.status(400).send('Error 400');
}
models.orders.post(userId, orders, totalPrice, (error, result) => {
if (error) {
console.log(error)
res.status(500).send('조회 실패');
} else {
res.status(201).json(result);
}
})
},
},
};
Model/index.js
const db = require('../db');
module.exports = {
items: {
get: (callback) => {
//Cmarket의 모든 상품을 가져오는 함수
const queryString = `SELECT * FROM items`;
db.query(queryString, (error, result) => {
callback(error, result);
});
},
},
orders: {
get: (userId, callback) => {
// 해당 유저가 작성한 모든 주문을 가져오는 함수
const queryString = `SELECT orders.id, orders.created_at, orders.total_price, items.name, items.price, items.image, order_items.order_quantity
FROM items
INNER JOIN order_items ON order_items.item_id = items.id
INNER JOIN orders ON orders.id = order_items.order_id
WHERE orders.user_id = ?`;
const params = [userId];
db.query(queryString, params, (err, result) => {
callback(err, result);
});
},
post: (userId, orders, totalPrice, callback) => {
// 해당 유저의 주문 요청을 데이터베이스에 생성하는 함수
const queryString = `INSERT INTO orders (user_id, total_price) VALUES ?`;
console.log(queryString);
const params = [[userId, totalPrice]];
db.query(queryString, [params], (err, result) => {
if (result) {
const queryString2 = `INSERT INTO order_items (order_id, item_id, order_quantity) VALUES ?`;
const params2 = orders.map( el => {
return [result.insertId, el.itemId, el.quantity];
});
db.query(queryString2, [params2], (err, result) => {
callback(err, result);
});
}
else {
callback(err, result);
}
});
}
},
};