안녕세계

[SK고용디딤돌] Node.js (7/10) - 6주차 본문

[SK고용디딤돌] Node.js (7/10) - 6주차

Junhong Kim 2016. 8. 12. 17:59
728x90
반응형

* REST API 설계할 때 가장 중요한 것은? collection 을 찾아내는 것 (엔티티와 1:1로 매핑되지 않는다)


- collection (마운트 포인트 4개)

1) orders

2) customers

3) branches

4) menus



- Express 서버 기초 생성 방법 -


0) 프로젝트 생성


1) 마운트 4개 생성 index.js 활용

var express = require('express');
var router = express.Router();

router.get('/', function(req, res, next) {
res.send({
message: 'orders'
});
});

module.exports = router;

※ render -> send로 변경


2) app.js에서 모듈을 로딩

var order = require('./routes/order');
var customer = require('./routes/customer');
var branch = require('./routes/branch');
var menu = require('./routes/menu');


3) 마운트 포인트 매핑

app.use('/orders', order);
app.use('/customers', customer);
app.use('/branches', branch);
app.use('/menus', menu);



- 주문 시스템을 만들어 보자 -


1) 주문 목록 조회

2) 주문 생성

3) 주문 조회

4) 주문 변경


var express = require('express');

var router = express.Router();

// 주문 목록 조회, GET /orders
// 1) 일자 (start date ~ end date)
// 2) 메뉴 (menus or menu_ids)
// 3) 지점 (branches or branch_ids)
// 4) 고객 (customer or customer_id)
// 5) 총주문가격 (start price ~ end price)
router.get('/', function(req, res, next) {
var data = {};
var message = '';
var results = [];

if (req.url === '/') { // 주문 목록 조회
message = 'list orders';
results.push({

});
data.results = results;
} else {
var startdate = req.query.startdate;
var enddate = req.query.enddate;
var menus = req.query.menus;

// 일자 검색
if (startdate) {
message = 'search orders with dates';
if (startdate === enddate || !enddate) { // 특정 일자 조회
results.push({

});
} else { // 특정 기간 조회
results.push({

});
}
data.startdate = startdate;
data.enddate = enddate;
data.results = results;
}
}

// 메뉴 검색
if (menus) {
message = 'search orders with menus';
data.menus = menus;
data.results = results;
}

// 지점 검색
if (branches) {
message = 'search orders with branches';
data.branches = branches;
data.results = results;
}

// 고객 검색
if (customer) {
message = 'search orders with customer';
data.customer = customer;
data.results = results;
}
res.send({
message: message,
data: data
});
});

//주문 생성, POST /orders
router.post('/', function(req, res, next) {
var details = [];
console.log(req.body.branch_menu_ids.length);
for(var i = 0 ; i < req.body.branch_menu_ids.length ; i ++)
details.push({
branch_menu_ids : req.body.branch_menu_ids[i],
quantities : req.body.quantities[i]
});

res.send({
message : 'received an order!!!',
result : {
order : {
customer_id : req.body.customer_id,
branch_id : req.body.branch_id,
},
details: details
}
});
});

//특정주문 조회
// :id 동적라우팅 파라미터
router.get('/:id', function(req, res, next) {
res.send({
message :'read order!!!',
});
});

//주문변경
router.put('/:id', function(req, res, next) {
var details = [];
for(var i = 0 ; i < req.body.branch_menu_ids.length ; i ++)
details.push({
branch_menu_ids : req.body.branch_menu_ids[i],
quantities : req.body.quantities[i]
});
res.send({
message : 'update order!!!',
change : {
menu_order_id : req.params.id,
details: details
}
});
});

module.exports = router;



- MySQL 연동 예제 -


※ 로컬 환경변수 설정 [Run/Edit Configurations]




※ 데이터베이스 정보를 로컬 환경변수에 저장한다.




※ host에 MySQL Hostname을 입력한다. (즉, AWS Host Address)



[연동 확인 app.js]

var mysql = require('mysql');
var async = require('async');

// DB연결할 정보
var dbConfig = {
host : process.env.DB_HOST,
user : process.env.DB_USER,
password : process.env.DB_PASSWORD,
database : process.env.DB_NAME
};
//매개변수의 정보를 갖고있는 DB와의 Connection과 관련 된 정보를 만들어 객체로 반환한다.
var dbConn = mysql.createConnection(dbConfig);
// 우리는 이 객체를 이용해서 쿼리를 던질 수 있다. 첫번째 매개변수를 쿼리를, 두번째 매개변수로 배열을 세번쨰로 콜백

var sql ='select id, name, price from menu';
dbConn.query(sql, function(err, results) { // select 넘기면 배열이 넘어감
if(err) {
console.log(err);
return;
}
async.each(results, function(row, callback) {
console.log(row);
callback();
}, function(err) {
if(err) {
console.log(err);
}
dbConn.end();
});
});


[연동 Test app2.js]

/**
* Created by Tacademy on 2016-08-12.
*/
var mysql = require('mysql');
var async = require('async');

// DB연결할 정보
var dbConfig = {
host : process.env.DB_HOST,
user : process.env.DB_USER,
password : process.env.DB_PASSWORD,
database : process.env.DB_NAME
};
//매개변수의 정보를 갖고있는 DB와의 Connection과 관련 된 정보를 만들어 객체로 반환한다.
var dbConn = mysql.createConnection(dbConfig);
// 우리는 이 객체를 이용해서 쿼리를 던질 수 있다. 첫번째 매개변수를 쿼리를, 두번째 매개변수로 배열을 세번쨰로 콜백

var sql ='select bm.id bmid, b.id bid, b.name bname, m.id mid, m.name mname ' +
'from branch b join branch_menu bm on (b.id = bm.branch_id) ' +
'join menu m on (bm.menu_id = m.id) ' +
'where b.id = ?'; // ? :place order 문자

dbConn.query(sql, [1], function(err, results) { // select 넘기면 배열이 넘어감, 두번째는 place order 문자를 순서대로 넣는다.
if(err) {
console.log(err);
return;
}
async.each(results, function(row, callback) {
console.log(row.bmid + ' | ' + row.bid + ' | ' + row.bname + ' | ' + row.mid + ' | ' + row.mname);
callback();
}, function(err) {
if(err) {
console.log(err);
}
dbConn.end();
});
});

※ SQL문 작성할 때 공백(space)처리해야함을 주의




[InsertID = last_insert_id()]



[Query Transactions]



[트랜잭션 처리 app3.js - 주문생성]

/**
* Created by Tacademy on 2016-08-12.
*/
var mysql = require('mysql');
var async = require('async');

var branch_id = 2;
var customer_id = 1;

var menu_order_details = [
{
branch_menu_id: 26,
quantity: 2,
price: 11000
},
{
branch_menu_id: 27,
quantity: 3,
price: 12000
}
]
// node app3.js [branch_id] [ customer_id] [branch_menu_id] [quantity] [menu_price]

var dbConfig = {
host : process.env.DB_HOST,
user : process.env.DB_USER,
password : process.env.DB_PASSWORD,
database : process.env.DB_NAME
};

var sql_insert_menu_order = 'insert into menu_order (branch_id, customer_id) ' +
'values (?, ?)';
var sql_insert_menu_order_details = 'insert into menu_order_details(menu_order_id, branch_menu_id, quantity, price) ' +
'values (?, ?, ?, ?)';

var dbConn = mysql.createConnection(dbConfig);
dbConn.beginTransaction(function(err) {
if (err) {
return console.error(err);
}
async.waterfall([insertMenuOrder, insertMenuOrderDetailsEach], function(err) {
if (err) {
return dbConn.rollback(function() {
console.error('rollback....');
});
}
dbConn.commit(function() {
console.log('commit...');
dbConn.end();
})
});
});

function insertMenuOrder(callback) {
dbConn.query(sql_insert_menu_order, [branch_id, customer_id], function(err, result) {
if (err) {
callback(err);
}
console.log('result.insertId : ' + result.insertId);
callback(null, result.insertId);
});
}

function insertMenuOrderDetailsEach(insertId, callback) {
async.each(menu_order_details, function(item, done) {
insertMenuOrderDetails(insertId, item.branch_menu_id, item.quantity, item.price, done);
}, function(err) {
if (err) {
callback(err);
} else {
callback(null);
}
})
}

function insertMenuOrderDetails(insertId, branch_menu_id, quantity, price, callback) {
dbConn.query(sql_insert_menu_order_details, [insertId, branch_menu_id, quantity, price], function (err, result) {
if (err) {
callback(err);
} else {
callback(null);
}
});
}


[ 주문변경 app4.js ]

/**
* Created by Tacademy on 2016-08-12.
*/
var mysql = require('mysql');
var async = require('async');

var dbConfig = {
host : process.env.DB_HOST,
user : process.env.DB_USER,
password : process.env.DB_PASSWORD,
database : process.env.DB_NAME
};

var quantity = 10;
var menu_order_id = 36170;
var branch_menu_id = 26;

var sql_update_menu_order_details = 'update menu_order_details md join branch_menu bm on (md.branch_menu_id = bm.id) ' +
'set quantity = ? ' +
'where menu_order_id = ? and branch_menu_id = ?';

var dbConn = mysql.createConnection(dbConfig);

dbConn.query(sql_update_menu_order_details, [quantity, menu_order_id, branch_menu_id], function(err, result) {
if(err) {
console.log(err);
return;
}
dbConn.end();
});



[일자별 조회 app5.js]

/**
일자별 조회
*/
var mysql = require('mysql');
var async = require('async');

var page = parseInt(process.argv[2]) || 1;
var count = parseInt(process.argv[3]) || 10;
var startdate = '2015-01-05';
var enddate = '2015-01-10';
//연결 정보 npm mysql API문서 보면 된다.
//이거를 환경변수에 넣고 써야 보안이 좋다. run - edit
var dbConfig = {
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME
};

//var sql = 'SELECT id, name, price FROM menu';

//반드시 끝에는 공백을 처리해줘야한다. 그래야 select from 사이를 구분 할 수 있다.
// 바뀌는 부분은 ?이거다 이게 플레이스 홀더
//dbConn.query()에서 [] 플레이스홀더다.
/*var sql =
'select bm.id bmid, b.id bid, b.name bname, m.id mid, m.name mname ' +
'from branch b join branch_menu bm on (b.id = bm.branch_id) ' +
'join menu m on (bm.menu_id = m.id) ' +
'where b.id = ? ';
*/
var sql = '';
var sql_params = [];

var sql1 =
'SELECT mo.id order_id, convert_tz(mo.order_dtime, ?, ?) ktc, b.name branch_name, c.name cus_name, sum(md.quantity * md.menu_price) total_price ' +
'from branch b join menu_order mo on (b.id = mo.branch_id) ' +
'join menu_order_details md on (md.menu_order_id = mo.id) ' +
'join customer c on (c.id = mo.customer_id) ' +
'where mo.order_dtime = str_to_date(?, "%Y-%m-%d") ' +
'group by mo.id ' +
'order by mo.id desc ' +
'limit ?, ?';
var sql2 =
'SELECT mo.id order_id, convert_tz(mo.order_dtime, ?, ?) ktc, b.name branch_name, c.name cus_name, sum(md.quantity * md.menu_price) total_price ' +
'from branch b join menu_order mo on (b.id = mo.branch_id) ' +
'join menu_order_details md on (md.menu_order_id = mo.id) ' +
'join customer c on (c.id = mo.customer_id) ' +
'where mo.order_dtime between str_to_date(?, "%Y-%m-%d") and str_to_date(?, "%Y-%m-%d") ' +
'group by mo.id ' +
'order by mo.id desc ' +
'limit ?, ?';

if(!enddate) {
sql = sql1;
sql_params = ["+00:00", "+09:00", startdate, count * (page - 1), count];
} else {
sql = sql2;
sql_params = ["+00:00", "+09:00", startdate, enddate, count * (page - 1), count];
}
var dbConn = mysql.createConnection(dbConfig);
dbConn.query(sql, sql_params , function (err, results) {
if (err) {
console.log(err);
return;
}
async.each(results, function (row, callback) {
console.log(row);
callback();
}, function (err) {
if (err) {
console.log(err);
return;
}
});
dbConn.end();
});


728x90
반응형
Comments