-
[SW 정글 104일차] 나만의 무기 12일차 (라우터로 만들기)기타/SW 사관학교 정글 2021. 11. 15. 01:50
오늘은 지금까지 app.js(서버 코드의 모임)에 작성한 API들을 라우터로 만드는 작업을 했다.
API가 많아짐에 따라서 코드의 복잡도가 높아지고 이 복잡도를 낮추는 방법이 라우터이다.
라우터를 만들기 위해서는 express 프레임워크에서 제공하는 Router라는 객체를 사용하면 된다.
(참고자료: https://expressjs.com/ko/4x/api.html#router)
일단은 router를 저장하는 폴더를 새로 생성했다.
(우리의 프로젝트에서는 routes라는 폴더 이름을 사용했다.)
내가 만든 API 중에 router로 만들 API는 챌린지 생성 API, 생명체 생성 API가 있다.
이 외에도 3개가 더 있는데 router 파일명을 어떻게 할지, 다른 팀원이 만든 API와 같은 파일에서 관리할지를 회의를 통해 정해야해서 일단은 2개만 router로 만들었다.
router로 만들기 전에 app.js에 있던 코드는 아래와 같다.
const path = require('path'); const dotenv = require("dotenv"); dotenv.config({ path: path.join(__dirname, "./.env") }); //미들웨어 const express = require('express'); const bodyParser = require('body-parser'); const helmet = require('helmet'); const schedule = require('node-schedule'); const port = 3001 const app = express(); app.use(helmet()); app.use(bodyParser.urlencoded({ extended: false })); const mysql = require('mysql'); const connection = mysql.createConnection({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, }); // 챌린지 생성 api app.post('/challenge_process', function(req, res){ console.log(req.body); const max_user = parseInt(req.body.max_user); const cnt_of_week = parseInt(req.body.cnt_of_week); const life = parseInt(req.body.life); connection.query('INSERT INTO Challenge (challengeName, challengeContent, createUserNickName, maxUserNumber, cntOfWeek, life) VALUES (?, ?, ?, ?, ?, ?)', [req.body.challenge_name, req.body.challenge_content, req.user.nickname, max_user, cnt_of_week, life], function(error, results){ console.log(req.user.id, results); connection.query('INSERT INTO user_info_has_Challenge (user_info_id, Challenge_id) VALUES (?, ?)', [req.user.id, results.insertId]) res.redirect(`/challenge/?id=${results.insertId}`) }) }); // 생명체 생성 api app.post('/create_alien', function(req, res){ connection.query('INSERT INTO Alien (user_info_id, Challenge_id, alienName, Alien_image_url, auth_day) VALUES (?, ?, ?, ?, ?)', [req.user.id, req.challenge_id, 'aa', 'url1']); connection.query('UPDATE Challenge set participantNumber = participantNumber + 1 where id = ?', [req.parms.id]); //challenge table과 join해서 total_auth_cnt(주 몇회인지) 업데이트하거나 front에서 받아오기 }) app.listen(port, () => { console.log(`Example app listening at http://localhost:${port}`) console.log('연결성공'); });
위에 코드는 내가 작성한 5개의 API 중 2개만 긁어온 것이 약 60line정도 되는데 다른 팀원과의 API와 나의 남은 API를 합쳐놓으면 한 파일에 너무 많은 코드가 쌓여있을 것이고 오류가 났을 때 어디 코드가 문제인지 찾기도 힘들 것이다.
그래서 router로 만들어서 비슷한 성격을 가진 api를 따로 관리하게 해주는 작업을 한 것이다.
먼저, 라우터를 app.js에서 사용하기 위해서는 아래의 코드를 입력해준다.
const challengeRouter = require('./routes/challenge.js')(connection); const alienRouter = require('./routes/alien.js')(connection); app.use('/api/challenge', challengeRouter); app.use('/api/alien', alienRouter);
이렇게 코드를 입력해주면 내가 routes 폴더에 만든 challenge와 관련된 api와 alien과 관련된 api를 app.js에서 사용할 수 있다.
다음으로 challenge와 관련된 api인 challenge 생성 api를 가지고 있는 challenge.js파일 코드이다.
const express = require('express'); const router = express.Router(); module.exports = function (connection) { // 챌린지 생성 api router.post('/create_process', function(req, res) { console.log(req.body); const max_user = parseInt(req.body.max_user); const cnt_of_week = parseInt(req.body.cnt_of_week); const life = parseInt(req.body.life); connection.query('INSERT INTO Challenge (challengeName, challengeContent, createUserNickName, maxUserNumber, cntOfWeek, life) VALUES (?, ?, ?, ?, ?, ?)', [req.body.challenge_name, req.body.challenge_content, req.user.nickname, max_user, cnt_of_week, life], function(err1, results) { if (err1) { console.error(err1); } console.log('success insert new challenge information', results); connection.query('INSERT INTO user_info_has_Challenge (user_info_id, Challenge_id) VALUES (?, ?)', [req.user.id, results.insertId], function(err2, results) { if (err2) { console.error(err2); } console.log('success insert user_id and challenge_id', results); }); }); res.status(200).json({ msg: `You sent post data '${JSON.stringify(req.body)}'`, body: req.body, }); }); router.use(function (req, res, next) { res.status(404).json({ msg: 'Sorry cant post that!', body: req.body, }); }); router.use(function (err, req, res, next) { console.error(err.stack) res.status(500).json({ msg: 'Something broke!', body: req.body, }); }); return router; }
그리고 alien과 관련된 api인 challenge 생성 api를 가지고 있는 alien.js파일 코드이다.
const express = require('express'); const router = express.Router(); module.exports = function (connection) { router.post('/create_process', function(req, res){ connection.query('INSERT INTO Alien (user_info_id, Challenge_id, alienName, Alien_image_url, auth_day) VALUES (?, ?, ?, ?, ?)', [req.user.id, req.challenge_id, 'aa', 'url1']); connection.query('UPDATE Challenge set participantNumber = participantNumber + 1 where id = ?', [req.parms.id]); //challenge table과 join해서 total_auth_cnt(주 몇회인지) 업데이트하거나 front에서 주 몇회인지 받아오기 res.status(200).json({ msg: `You sent post data '${JSON.stringify(req.body)}'`, body: req.body, }); }); router.use(function (req, res, next) { res.status(404).json({ msg: 'Sorry cant post that!', body: req.body, }); }); router.use(function (err, req, res, next) { console.error(err.stack) res.status(500).json({ msg: 'Something broke!', body: req.body, }); }); return router; }
이렇게 관련 api들을 각각 router로 만들어 코드를 관리하니까 app.js에 있는 코드가 한결 간결해졌고 만약에 오류가 났어도 어느 코드가 문제인지를 쉽게 찾을 수 있을 것같다.
이제 프론트와 연동하는 일만 남았다.
그리고 이미지 파일이 저장될 일이 많아서 S3를 쓸지 말지를 고민하고 있고 native sql문으로 작성된 쿼리문을 ORM으로 바꿀지 말지를 고민 중에 있다.
ORM에 대해 알아봤을 떄에는 지금 우리 팀의 상황에서는 native sql을 쓰는 것을 사용하는 것이 좋다고 판단했지만 이렇게 지저분한 sql문들을 보니까 ORM을 썼을 시에 코드가 간결해지고 재사용성이 좋아진다면 공부를 해서 리팩토링을 해야겠다는 생각도 든다.
'기타 > SW 사관학교 정글' 카테고리의 다른 글
[SW 정글 106일차] 나만의 무기 14일차 (새로운 API 설계) (0) 2021.11.17 [SW 정글 105일차] 나만의 무기 13일차 (오늘 새로 배운 것) (0) 2021.11.15 [SW 정글 103일차] 나만의 무기 11일차 (API 마무리 후 정비) (0) 2021.11.14 [SW 정글 102일차] 나만의 무기 10일차 (생명체 사망 API) (0) 2021.11.13 AWS RDS time_zone 변경 (0) 2021.11.13