2020.코딩일지
[DB]im-sprint-cmarket-database/Cmarket ServerAPI[#MVC패턴][BEB 6th] 본문
WebServer&DB&CTI
[DB]im-sprint-cmarket-database/Cmarket ServerAPI[#MVC패턴][BEB 6th]
개발하는라푼젤 2022. 8. 9. 21:17728x90
코드스테이츠 블록체인 부트캠프 6기
(테스트마다 다르긴한데... 이번 스프린트는 npm test시, 서버 두개 모두 켜져있어야함.)
/server/들어가서 `npm start` 노드익스프레스 서버ON & `mysql.server start` 데이터베이스ON
혹시나 에러가 난다면 여기
server/routes/index.js부분 분기추가
더보기
server/routes/index.js
const express = require("express");
const router = express.Router();
const itemsRouter = require("./items");
const usersRouter = require("./users");
// TODO: Endpoint에 따라 적절한 Router로 연결해야 합니다.
router.use("/items", itemsRouter);
router.use("/users", usersRouter);
module.exports = router;
server/routes/items.js
const router = require('express').Router();
const controller = require('./../controllers');
// GET /items Router와 Controller를 연결합니다.
router.get('/', controller.items.get);
module.exports = router;
sercer/routes/위치에 users.js파일 추가 (controllers의 index.js참고해서 수정)
더보기
sercer/routes/users.js
const router = require("express").Router();
const controller = require("./../controllers");
router.get("/:userId/orders", controller.orders.get);
router.post("/:userId/orders", controller.orders.post);
module.exports = router;
controllers/index.js : (models/index.js참고하여)컨트롤러 작성 ‘메소드별 예외처리 및 status’
더보기
const models = require("../models");
module.exports = {
items: {
get: (req, res) => {
// * DB 접근 함수 실행 결과를 반환
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;
// TODO: 요청에 따른 적절한 응답을 돌려주는 컨트롤러를 작성하세요.
if (!userId) {
//예외처리1) userId가 없는경우
return res.status(401).send("Unauthorized user.");
}
models.orders.get(userId, (error, result) => {
//models/index.js참고하여 보내야할 인자확인
if (error) {
return res.status(500).send("Internal Server Error");
}
return res.status(200).json(result);
});
},
post: (req, res) => {
const userId = req.params.userId;
const { orders, totalPrice } = req.body;
// TODO: 요청에 따른 적절한 응답을 돌려주는 컨트롤러를 작성하세요.
if (!userId) {
//예외처리1) userId가 없는경우
return res.status(401), send("Unauthorized user");
}
if (!orders || !totalPrice) {
//예외처리2) 바디값이없는경우
return res.status(400).send("Bad request");
}
models.orders.post(userId, orders, totalPrice, (error, result) => {
//models/index.js참고하여 보내야할 인자확인
if (error) {
//에러일경우
return res.status(500).send("Internal Server Error");
} //정상적일경우
return res.status(201).send("Order has been created");
});
},
},
};
models/index.js : 쿼리문작성 (schema.sql참고하여)
items.get으로들어오면 상품내역보여주는 쿼리문
oders.get으로 들어오면 해당유저의 주문내용을 보여주는 쿼리문
oders.post로 들어오면 해당유저의 주문내용을 데이터베이스에 입력하는 쿼리문
- models/index.js에 보면 params로 넣었는데 [userId]하나만 넣기도하고 map으로 넣기도했다
🤖Database.Query(String, Object[]) 메서드
더보기
models/index.js
const db = require("../db");
//여기는 sql문법으로 연결된 데이터베이스와 CRUD를 할 수 있도록 함수가 구현되어있는 곳
module.exports = {
items: {
get: (callback) => {
// TODO: Cmarket의 모든 상품을 가져오는 함수를 작성하세요
const queryString = `SELECT * FROM items`;
db.query(queryString, (error, result) => {
console.log(result);
callback(error, result);
});
},
},
orders: {
get: (userId, callback) => {
// TODO: 해당 유저가 작성한 모든 주문을 가져오는 함수를 작성하세요
const sql = `SELECT orders.id, orders.created_at, orders.total_price, items.name, items.price, items.image, order_items.order_quantity
FROM orders
INNER JOIN order_items ON (orders.id = order_items.order_id)
INNER JOIN items ON (order_items.item_id = items.id)
WHERE (orders.user_id = ?)`;
// WHERE (users.id =${userId});
const params = [userId];
db.query(sql, params, (error, result) => {
// console.log(result);
callback(error, result);
});
},
post: (userId, orders, totalPrice, callback) => {
// TODO: 해당 유저의 주문 요청을 데이터베이스에 생성하는 함수를 작성하세요(INSERT INTO입력하는것!)
// orders: [{ quantity: 1, itemId: 2 },{ quantity: 1, itemId: 4 }]
const sql1 = `INSERT INTO orders (user_id, total_price) VALUES (?, ?)`;
const params = [userId, totalPrice];
db.query(sql1, params, (error, result) => {
if (result) {
const sql2 = `INSERT INTO order_items (order_id, item_id, order_quantity) VALUES ?`;
let params = orders.map((el) => [
//orders에 배열형식으로 넣기 좋은 map. [[],[]]이중배열을 만들어주기위한 []
//😎여러개의 레코드를 한번의 쿼리로 저장하려고 이중배열형태로 만들어 bulk insert 한것이다!
result.insertId,
el.itemId,
el.quantity,
]);
return db.query(sql2, [params], (error, result) => {
//이중배열을 또 묶...
callback(error, result);
});
}
callback(error, null);
});
},
},
};
(참고)schema.sql
더보기
schema.sql
CREATE TABLE users (
id INT AUTO_INCREMENT,
username varchar(255),
PRIMARY KEY (id)
);
CREATE TABLE items (
id INT AUTO_INCREMENT,
name varchar(255),
price INT,
image varchar(255),
PRIMARY KEY (id)
);
CREATE TABLE orders (
id INT AUTO_INCREMENT,
user_id INT,
total_price INT,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);
CREATE TABLE order_items (
id INT AUTO_INCREMENT,
order_id INT,
item_id INT,
order_quantity INT,
PRIMARY KEY (id)
);
ALTER TABLE orders ADD FOREIGN KEY (user_id) REFERENCES users (id);
ALTER TABLE order_items ADD FOREIGN KEY (order_id) REFERENCES orders (id);
ALTER TABLE order_items ADD FOREIGN KEY (item_id) REFERENCES items (id);
/* Execute this file from the command line by typing:
* mysql -u root < server/schema.sql -p -Dcmarket
* to create the database and the tables.*/
🤖 ${}달러사인으로넣는것은 sql injection공격에 대해 보호하기위해 (?,?)이렇게생긴 prepared 방식을 쓴다.
기본적으로 유저에게 받은 값을 직접 SQL로 넘기는것${}은 위험하다.
orders: {
get: (userId, callback) => {
// ..생략
WHERE (orders.user_id = ?)`;
const params = [userId];
//im-sprint-database/server/models/index.js의 예시
//--❌❌❌❌❌❌❌$달러사인방법은 비추❌❌❌❌❌❌❌
post: (userId, orders, totalPrice, callback) => {
// TODO: 해당 유저의 주문 요청을 데이터베이스에 생성하는 함수를 작성하세요(INSERT INTO입력하는것!)
// orders: [{ quantity: 1, itemId: 2 },{ quantity: 1, itemId: 4 }]
let sql1 = `INSERT INTO orders (user_id, total_price) VALUES (${userId}, ${totalPrice})`;
db.query(sql1, (err, result) => {
console.log(result);
let sql2 = `INSERT INTO order_items (order_id, item_id, order_quantity) VALUES ?`;
let params = orders.map((el) => [
result.insertId,
el.itemId,
el.quantity,
]);
console.log(params);
db.query(sql2, [params]);
callback(err, result);
});
},
'WebServer&DB&CTI' 카테고리의 다른 글
[데이터베이스]NoSQL:MongoDB = NoSQL도큐먼트DB[BEB 6th] (0) | 2022.08.11 |
---|---|
[DB]SQL Advanced-[BEB 6th] (0) | 2022.08.09 |
[DB]im-sprint-cmarket-database:test파일안돌고뭐해에러[BEB 6th][nodemon] app crashed - waiting for file changes before starting... (0) | 2022.08.09 |
[데이터베이스]MySQL사용 (macOS) (0) | 2022.08.08 |
basic-server(2)express로 refactoring / nodemon을써보자 (0) | 2022.08.05 |
Comments