[프로젝트] raspi_api | express 라우터 구성

dev2820·2021년 10월 16일
0

프로젝트: raspi_api

목록 보기
3/6

time router

제일 구성이 간단한 time router부터 만들겠습니다.
time router는 GET /time 요청이 들어오면 서버의 현재 시간을 반환하는 라우터입니다.

routes/time.js 를 다음과 같이 작성해줍니다.

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

router.get('/', function(req, res, next) {
    const time = new Date();
    const year = time.getFullYear();
    const month = ("0"+(time.getMonth()+1)).slice(-2);
    const date = ("0"+time.getDate()).slice(-2);
    const hours = ("0"+time.getHours()).slice(-2);
    const minutes = ("0"+time.getMinutes()).slice(-2);
    const seconds = ("0"+time.getSeconds()).slice(-2);
    res.send(`${year}/${month}/${date} ${hours}:${minutes}:${seconds}`);
});

module.exports = router;

databaseMiddleware.js

테이블을 사용하는 라우터를 구성하기 앞서 데이터베이스와 커넥션을 만들어주는 databaseMiddleware.js 미들웨어부터 구성해봅시다.

데이터베이스는 mariadb를 사용할 것이기 때문에 mysql 모듈을 받아 써야하는데, mysql2를 받아 promise를 적용해 DB에 접근해봅시다.

npm install mysql2

그 다음, mysql2를 써보기 전에, DB정보를 .env파일에 작성해 환경변수로 값을 가져옵시다.

HOST='[호스트]'
USER='[유저이름]'
PASSWORD='[비밀번호]'
DATABASE='[데이터베이스 이름]'
DB_PORT=[사용하는 포트]
LIMIT=[생성할 최대 연결 갯수]

위와 같이 DB에 대한 정보를 .env 에 작성해주면 app.jsrequire('dotenv').config() 코드가 .env 파일의 내용을 환경변수로 저장합니다.

이제 process.env.~~로 불러올 수 있는 것이죠.

databaseMiddleware.js를 작성해봅시다.

const { createPool } = require('mysql2/promise');

const pool = createPool({
        host:process.env.HOST,
        user:process.env.USER,
        password:process.env.PASSWORD,
        database:process.env.DATABASE,
        port: process.env.DB_PORT || 3306,
        connectionLimit: process.env.LIMIT || 10
});

const registConnection = async (req,res,next)=>{
    try {
        res.locals.conn = await pool.getConnection(async conn => conn);
        next();
    }
    catch(err) {
        next(err);
    }
}

module.exports = registConnection

createPool로 pool을 생성하고, request가 들어올때마다 getConnection으로 transaction을 가져와 res.locals에 넣어줍니다. 그리고 next로 다음 라우터로 connection을 넘기죠.
connection은 default로 최대 10개 생성하도록 작성하였습니다.

DB를 사용하는 라우터

이제 DB를 사용하는 라우터(cpu,io,memory,network,summary)를 작성합시다. 요청은 get만 가능합니다.

api 요청은 다음과 같이 구성합시다.

GET /[라우터이름]?limit=[column수]&fields=[필드명, ...]

예를 들어, summary 테이블에서 date, uptime, cpu_thermal을 5개 가져온다면

GET /summary?limit=5&fields=date,uptime,cpu_thermal과 같이 보내면 되는거죠. 5개를 가져온다는 것은, 가장 최근 column 5개를 가져온다는 뜻입니다. 쿼리는 다음과 같이 구성되겠죠.

SELECT [필드명,...] FROM summary_status ORDER BY date DESC LIMIT [column];

routes/summary.js 라우터는 다음과 같이 구성됩니다.

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

router.get('/', async function(req, res, next) {
    const conn = res.locals.conn;
    const limit = req.query['limit'];
    const fields = req.query['fields'];
    const query = `SELECT ${fields} FROM summary_status ORDER BY date DESC LIMIT ${limit}`;
    try {
        conn.beginTransaction();
        const [row,field] = await conn.query(query);
        conn.commit();
        conn.release();
        res.json(row);
    }
    catch(err) {
          conn.release();
          next(err);
    }
});

module.exports = router;

limit와 fields 정보는 request의 query에서 가져오고, DB connection은 res.locals에서 가져옵니다. 그리고 단순히 쿼리를 실행하고 connection을 반납하면 끝이죠. 만약 에러가 일어난다면 에러를 다음 라우터로 넘깁니다.(에러처리 라우터로 넘어가겠죠)

다른 라우터도 summary.js와 같습니다. 99%같아요. sql쿼리의 table이름만 바꿔주면 됩니다.

실행

이제 서버를 실행해봅시다.
서버가 간단하니 단순히 node로 실행해도 됩니다만, 저는 nodemon환경에서 테스트했습니다.
request는 postman을 통해 발생시켰습니다. 브라우저로도 같은 결과를 확인할 수 있습니다.

nodemon ./bin/www

time 요청

localhost:3000/time으로 요청하니 2021/10/16 15:14:07을 반환한 것을 볼 수 있습니다.

서버쪽도 GET /time 요청에 200으로 응답한 것을 볼 수 있습니다.

DB 요청

다음은 DB에서 직접 값을 읽어보죠.

localhost:3000/summary?limit=10&fields=date,uptime,cpu_thermal로 요청을 보냈습니다. summary 테이블에서 date,uptime,cpu_thermal 세 개의 필드를 뒤에서부터 10개 뽑아 보냅니다. db에 저장된 date가 GMT라 현재 시간과 9시간 차이가 나네요.

서버쪽도 200이 떴습니다.

서버는 이렇게 완성된 것 같네요. 다음글에선 cpu 활용을 위해 cluster를 적용시켜보겠습니다.

profile
공부,번역하고 정리하는 곳

0개의 댓글