[프로젝트] raspi_api | express 앱 구성

dev2820·2021년 10월 16일
0

프로젝트: raspi_api

목록 보기
2/6

생성

express앱은 express-generator를 통해 뼈대를 만들고 시작하겠습니다. 사실 서버 구성이 복잡하지 않아서 직접 express앱을 만들어도 상관없습니다.

express 앱은 이런식으로 구성해보죠.

DB에 cpu,io,memory,network,summary 테이블이 존재하므로, 각각 라우터로 만들어줍니다. cpu router는 cpu table의 정보를 읽고 반환하는 식으로요. 그리고 테이블에 접근하는 각 라우터는 앞단에 database middleware를 두어 pool을 생성하고 transaction을 생성하도록 만듧니다. request는 database middleware를 거쳐 transaction을 할당받고 각 라우터로 이동하는 셈이죠.

time 라우터는 단순하게 서버의 시간을 반환하는 api입니다.

테이블 구조가 궁금하다면 여기를 참고해 주세요.

# express generator가 안깔려있다면
npm install express-generator -g

# express 앱 생성, view는 안쓸거라 pug나 ejs중 아무거나 쓰면 됩니다.
express --view=ejs raspi_api

다음은 만들어야하는 폴더 구조입니다.

라우터

express generator가 bin, public, routes, views 폴더를 생성할텐데 views는 안쓸거니
지워버립니다. routes는 user.jsindex.js가 있는데 둘다 지우고 cpu.js,io.js,memory.js,network.js,summary.js,time.js 파일을 생성합니다.

다음으로 app.js에 라우터를 등록해줘야지요

// app.js
const createError = require('http-errors');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');

/*라우터 불러오기*/
const timeRouter = require('./routes/time');
const summaryRouter = require('./routes/summary');
const cpuRouter = require('./routes/cpu');
const memoryRouter = require('./routes/memory');
const ioRouter = require('./routes/io');
const networkRouter = require('./routes/network');
const app = express();

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

/*라우터 등록*/
app.use('/time',timeRouter);
app.use('/summary',summaryRouter);
app.use('/cpu',cpuRouter);
app.use('/memory',memoryRouter);
app.use('/io',ioRouter);
app.use('/network',networkRouter);

...

views를 등록하는 부분은 빼버립니다. 안쓰니까요. 그리고 app.use로 각 라우터를 등록합니다.

미들웨어

다음으로 미들웨어를 저장할 폴더를 만듧시다.
middlewares 폴더를 만들고 databaseMiddleware.js를 만듧니다.

미들웨어는 데이터베이스에 접근하는 라우터 앞단에 위치할 것입니다. app.js를 다시 수정합시다.

// app.js
const createError = require('http-errors');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');

const addConnection = require('./middlewares/databaseMiddleware'); // 미들웨어 불러오기

const timeRouter = require('./routes/time');
const summaryRouter = require('./routes/summary');
const cpuRouter = require('./routes/cpu');
const memoryRouter = require('./routes/memory');
const ioRouter = require('./routes/io');
const networkRouter = require('./routes/network');
const app = express();

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

/*미들웨어 등록*/
app.use('/time',timeRouter);
app.use('/summary',addConnection,summaryRouter);
app.use('/cpu',addConnection,cpuRouter);
app.use('/memory',addConnection,memoryRouter);
app.use('/io',addConnection,ioRouter);
app.use('/network',addConnection,networkRouter);

...

.env

다음으로 데이터베이스에 대한 정보를 저장할 .env파일을 만듧니다. .env파일은 환경변수를 저장하는 파일로 dotenv 모듈을 이용하면 됩니다.

npm install dotenv

들어갈 내용은 다음글에서 다루죠. 일단 app.js에 .env의 내용을 환경변수로 등록합시다.

// app.js
const createError = require('http-errors');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
require('dotenv').config(); // dotenv 사용

const addConnection = require('./middlewares/databaseMiddleware');

...

.gitignore

.gitignore는 특정 파일들이 git에 감지되지 않도록합니다. .env파일엔 DB 비밀번호도 들어가기때문에 .gitignore가 필수입니다.

# .gitignore
node_modules
.env

.gitignore는 위와 같이 구성하면 됩니다.

최종 app.js 구성

추가적으로 error handler에서 에러 페이지를 반환하는게 아니라 에러 메세지를 반환하도록 수정해줍시다.

...
app.use('/time',timeRouter);
app.use('/summary',addConnection,summaryRouter);
app.use('/cpu',addConnection,cpuRouter);
app.use('/memory',addConnection,memoryRouter);
app.use('/io',addConnection,ioRouter);
app.use('/network',addConnection,networkRouter);

// catch 404 and forward to error handler
// 알 수 없는 쿼리는 404처리
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};
  console.log(err)
  // render the error page
  res.status(err.status || 500);
  res.json({//메세지를 반환하도록 수정(res.render - > res.json)
    'message': err.message
  });
});

module.exports = app;

최종 app.js입니다.

const createError = require('http-errors');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
require('dotenv').config();

const addConnection = require('./middlewares/databaseMiddleware');

const timeRouter = require('./routes/time');
const summaryRouter = require('./routes/summary');
const cpuRouter = require('./routes/cpu');
const memoryRouter = require('./routes/memory');
const ioRouter = require('./routes/io');
const networkRouter = require('./routes/network');
const app = express();

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/time',timeRouter);
app.use('/summary',addConnection,summaryRouter);
app.use('/cpu',addConnection,cpuRouter);
app.use('/memory',addConnection,memoryRouter);
app.use('/io',addConnection,ioRouter);
app.use('/network',addConnection,networkRouter);

// catch 404 and forward to error handler
// 알 수 없는 쿼리는 404처리
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};
  console.log(err)
  // render the error page
  res.status(err.status || 500);
  res.json({
    'message': err.message
  });
});

module.exports = app;

각 라우터의 구성은 다음글에서 다루도록 합시다.

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

0개의 댓글