드디어! 백엔드 작업을 한다!
☑️ mysql에 neti 데이터베이스 생성하기
☑️ 회의실 테이블 생성하고 데이터 삽입하기
☑️ express로 회의실 테이블 CRUD API 만들기
mysql 설치는 brew 로 하거나
공식 홈페이지에서 Community server 를 받아 설치하면 된다.
mysql에 들어가서
mysql -uroot -p
neti 라는 데이터베이스를 만들자.
create database neti;
만든 neti로 들어가서
use neti;
예전 기억을 되살려 회의실 테이블을 만들었다.
이름, 설명, 온라인 URL, 사용 여부 정도가 사용 될거고 나머지는 그냥 나만의 기본 셋이다. 😎
CREATE TABLE IF NOT EXISTS `TBL_MEETING_ROOM`
(
ID BIGINT NOT NULL AUTO_INCREMENT,
NAME VARCHAR(50) NOT NULL,
DESCRIPTION VARCHAR(50) NOT NULL,
ONLINE_URL VARCHAR(125),
USE_YN Boolean,
CREATED DATETIME(6) NOT NULL,
CREATOR VARCHAR(20),
UPDATED DATETIME(6) NOT NULL,
UPDATER VARCHAR(20),
PRIMARY KEY (ID)
)
DEFAULT CHARACTER SET utf8
COLLATE utf8_general_ci
ENGINE = INNODB;
회의실은 자주 수정되는 항목이 아니라서 테스트겸 데이터도 미리 넣어주자.
4개만 넣어주자.
INSERT INTO TBL_MEETING_ROOM (NAME, DESCRIPTION, ONLINE_URL, USE_YN, CREATED, CREATOR, UPDATED, UPDATER) VALUES ('1번', '1번 회의실', null, true, now(), 'admin', now(), 'admin');
INSERT INTO TBL_MEETING_ROOM (NAME, DESCRIPTION, ONLINE_URL, USE_YN, CREATED, CREATOR, UPDATED, UPDATER) VALUES ('2번', '2번 회의실', null, true, now(), 'admin', now(), 'admin');
INSERT INTO TBL_MEETING_ROOM (NAME, DESCRIPTION, ONLINE_URL, USE_YN, CREATED, CREATOR, UPDATED, UPDATER) VALUES ('3번', '3번 회의실', null, true, now(), 'admin', now(), 'admin');
INSERT INTO TBL_MEETING_ROOM (NAME, DESCRIPTION, ONLINE_URL, USE_YN, CREATED, CREATOR, UPDATED, UPDATER) VALUES ('4번', '4번 회의실', null, true, now(), 'admin', now(), 'admin');
잘 들어갔나 볼까?
SELECT * FROM TBL_MEETING_ROOM;
음~ 퍼펙 ✨
이제 본격적으로 express 에 이어붙여보자.
우선 npm의 mysql 패키지를 설치해주어야 한다.
npm install --save mysql
설치 뒤backend/database.js
파일 생성!
const mysql = require('mysql');
const connection = mysql.createConnection({
host : 'localhost',
user : '아이디',
password : '비밀번호',
database : 'neti'
});
connection.connect();
module.exports = connection;
백엔드 구조 짜는데 익숙하지 않아서 일단 다 때려넣었다.
이렇게 만든 mysql 커넥션을 app.js 에서 사용하게 해주어야겠지?
backend/app.js
오픈
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
// router
const indexRouter = require('./routes/index');
const usersRouter = require('./routes/users');
const meetingroomsRouter = require('./routes/meetingrooms');
// db
// import connection from './database';
const connection = require('./database');
const app = express();
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
// ui 안쓰니까 생략한다
// app.use(express.static(path.join(__dirname, 'public')));
// samples
app.use('/', indexRouter);
app.use('/users', usersRouter);
// meetingroom
app.use('/meetingrooms', meetingroomsRouter);
module.exports = app;
이제 새로 추가하게 될 회의실 라우터(meetingroomsRouter)도 미리 추가해주었다.
기본으로 있던 샘플들도 일단 두자.
backend/routes/meetingrooms.js
파일을 새로 만들자.
연결 테스트 단계이므로 READ(=GET) 만 만들어보겠다.
const express = require('express');
const router = express.Router();
const connection = require('../database');
// import connection from '../database';
// connection.connect();
/* GET meetingrooms listing. */
router.get('/', function(req, res, next) {
// 쿼리 날려서 가져오기
connection.query('SELECT * from TBL_MEETING_ROOM', (error, rows, fields) => {
if (error) {
console.error(error);
res.status(500).send('Internal Server Error');
}
console.log(': ', rows);
res.send(rows);
});
});
module.exports = router;
쓰다보니 es6 문법이 안먹히더라... 내일은 이걸 해야겠다 마음먹으면서 npm run start
명령어로 서버를 띄우자.
테스트용이니까 거창하게 포스트맨을 띄우지 않고 curl 로 테스트하자.
curl -v http://localhost:5051/meetingrooms | json_pp
굿! 잘 나온당🍻
사실 의미가 없긴 하지만 이왕 R을 만든김에 CUD도 같이 만들어두자.
/* POST meetingrooms listing. */
router.post('/', function(req, res, next) {
const params = req.body;
const query = `INSERT INTO TBL_MEETING_ROOM (NAME, DESCRIPTION, ONLINE_URL, USE_YN, CREATED, CREATOR, UPDATED, UPDATER) VALUES
('${params.name}', '${params.description}', '${params.onlineUrl}', 1, now(), 'admin', now(), 'admin');`;
console.log('[POST] meetingrooms query: ', query);
connection.query(query, (error, result) => {
if (error) {
console.error(error);
res.status(500).send('Internal Server Error');
}
console.log('[POST] meetingrooms result: ', result);
if (Number.isNaN(result.insertId) || result.insertId < 0) {
res.status(500).send('Item create failed.');
}
res.send({
id: result.insertId,
});
});
});
/* PUT meetingrooms listing. */
router.put('/:id', function(req, res, next) {
if (!req.params.id) {
res.status(500).send('Id is not exist.');
return;
}
const params = req.body;
const query = `UPDATE TBL_MEETING_ROOM SET ${Object.keys(params).map(key => `${key} = '${params[key]}'`).join(',')}, updated = now() WHERE id = ${req.params.id};`;
console.log('[PUT] meetingrooms query: ', query);
connection.query(query, (error, result) => {
if (error) {
console.error(error);
res.status(500).send('Internal Server Error');
}
console.log('[PUT] meetingrooms result: ', result);
res.send({});
});
});
/* DELETE meetingrooms listing. */
router.delete('/:id', function(req, res, next) {
if (!req.params.id) {
res.status(500).send('Id is not exist.');
return;
}
const query = `DELETE FROM TBL_MEETING_ROOM WHERE id = ${req.params.id};`;
console.log('[DELETE] meetingrooms query: ', query);
connection.query(query, (error, result) => {
if (error) {
console.error(error);
res.status(500).send('Internal Server Error');
}
console.log('[DELETE] meetingrooms result: ', result);
res.send({});
});
});
테스트는 포스트맨으로 대충 완료함.
이로써 백이랑 프론트의 기초 공사는 다 했다.
내일은 backend 소스도 es6를 사용할 수 있도록 babel을 추가하고, API 호출 시 사용되는 response /request 에 일정한 규칙을 부여해서 객체화 할 예정이다.😊
좀 더 우아한 소스를 쓸 수 있게 공부도 더 해야겠다 💪✨