토큰 관리
완성 코드 참고
C:\Workspace\metacamp-backend2-origin
Express
Node.js를 위한 간결한 웹 프레임워크 : 구조를 잡아준다
거의 모든 nodejs 프로젝트는 express로 되어 있다. 그래서 한묶음으로 취급한다.
그래도 이력서엔 nodejs+express로 적자.
express로 짠 nodejs엔 프론트엔드 화면이 존재한다.
설치 설명 링크
npm install express-generator -g
프로젝트 생성
express --ejs nodeproj
명령어 express / ejs라는 형식으로 express에 프론트엔드 화면을 만들겠다 / 생성할 프로젝트명
nodemon
소스코드를 감지해서 수정되면 자동으로 재시작
설치
npm install nodemon -g
package.json에 dev 스크립트 추가(개발모드)
"scripts": {
"start": "node ./bin/www",
"dev": "nodemon ./bin/www"
},
eslint 설치
npm install -g eslint
init하기 위해 전역 옵션 설치
설정
{
"env": {
"commonjs": true,
"es6": true,
"node": true
},
"extends": [
"airbnb-base"
],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018
},
"rules": {
"linebreak-style": 0,
"no-unused-vars": ["warn", { "vars": "all", "args": "after-used", "ignoreRestSiblings": false }]
}
}
linebreak-style: 0 => Expected linebreaks to be 'LF' but found 에러를 피하기 위함
VSCode 설정
/.vscode/settings.json
{
"eslint.validate": ["javascript", "html"],
"eslint.alwaysShowStatus": true,
"editor.tabSize": 2,
"git.ignoreLimitWarning": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
}
이제 저장할 때 자동변환 됨
이때 /bin/www 파일은 자동변환 되지 않도록 /* eslint-disable */ 설정
환경설정
/.env
NODE_ENV=development
PORT=3000
LOGGER_LEVEL=debug
DB_HOST=localhost
DB_PORT=5432
DB_DATABASE=metacamp_dev
DB_ID=postgres
DB_PASS=postgres
DB_DIALECT=postgres
env : environment variable / 환경변수(OS에서 사용 가능한 변수)
venv : virtual environment vaiable
echo %환경변수명% : 환경변수 출력(% : 환경변수 / 리눅스에서는 $환경변수명)
대표적인 환경변수 : PATH
라이브러리 설치
dotenv
env 파일을 환경변수로 읽어온다.
npm install dotenv --save
bodyparser
npm install body-parser --save
bodyparser 설정
/app.js
// ...
const logger = require('morgan');
const bodyParser = require('body-parser');
// ...
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
// ...
logger
백엔드에선 console.log 안쓰는 게 좋음. 대신 로그 파일 활용
로깅 처리를 위한 winston 설치
npm install winston --save
매일 날짜에 맞춰 로그를 자동으로 생성해주는 라이브러리 설치
npm install winston-daily-rotate-file --save
설정
/lib/logger.js
const { createLogger, format, transports } = require('winston');
require('winston-daily-rotate-file');
const dotenv = require('dotenv');
const fs = require('fs');
dotenv.config();
// logger level 세팅
const loggerLevel = process.env.LOGGER_LEVEL || 'info';
// const { env } = envConfig;
const logDir = 'log';
// Log only if info.level less than or equal to this level
// { error: 0, warn: 1, info: 2, verbose: 3, debug: 4, silly: 5 }
// log directory
if (!fs.existsSync(logDir)) {
fs.mkdirSync(logDir);
}
// log file
const dailyRotateFileTransport = new transports.DailyRotateFile({
// 로그파일 출력 세팅
filename: `${logDir}/%DATE%.log`,
datePattern: 'YYYY-MM-DD',
format: format.combine(
format.printf(
(info) => `${info.timestamp}[${info.level}] ${info.message}`,
),
),
});
const logger = createLogger({
// 로거 환경 세팅(기본 세팅)
level: loggerLevel,
format: format.combine(
// format.label( { label: 'label123' }),
format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss.SSS' }),
format.json(),
),
transports: [
new transports.Console({
// 콘솔 출력 세팅
level: loggerLevel,
format: format.combine(
format.colorize(),
format.printf(
(info) => `${info.timestamp}[${info.level}] ${info.message}`,
),
),
}),
dailyRotateFileTransport,
],
});
module.exports = logger;
/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 bodyParser = require('body-parser');
const logger = require('./lib/logger');
//...
const app = express();
logger.info('app start');
// ...
// 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(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
Notepad++에서 열어서 확인하면 편함
logger 사용 예제
debug 레벨일 경우 debug까지 나온다.
info 레벨일 경우 info까지 나온다.
환경 설정은 nodemon이 안먹히기 때문에 껐다가 다시 npm run dev 해줘야 한다.
cors
설치
npm install cors --save
환경 설정
/config/corsConfig.json
{
"origin": ["http://localhost:3000"],
"methods": ["OPTIONS", "GET", "POST", "HEAD", "PUT", "DELETE"]
}
origin에 적힌 주소 허용
methods에 들어가는 요소 허용
주의! cors 정책에서 origin은 등록하지말고 전부 막도록 해야한다.
(font에서 접근할 때 proxy를 이용해서 접근하도록 해야한다.)
적용
//...
const cors = require('cors');
const corsConfig = require('./config/corsConfig.json');
const logger = require('./lib/logger');
//...
app.use(cors(corsConfig));
app.use(express.json());
//...
DB 연동
DBeaver 테이블 편집
버전 확인
ORM Object Relational Mapping
OOP 객체지향
RDB 관계지향 : table
객체지향 - 관계지향 변환을 위해 ORM 방식 탄생
Sequelize ORM
버전 6 사용
DB 클라이언트 설치(postgresql)
npm install pg
sequelize 설치
npm install sequelize --save
sequelize 접속 설정
const Sequelize = require('sequelize');
const dotenv = require('dotenv');
dotenv.config(); // .env 파일 불러오기
const db = {
username: process.env.DB_ID,
password: process.env.DB_PASS,
database: process.env.DB_DATABASE,
host: process.env.DB_HOST,
port: process.env.DB_PORT,
dialect: process.env.DB_DIALECT,
};
// sequelize 생성
const sequelize = new Sequelize(
db.database,
db.username,
db.password,
{
host: db.host,
port: db.port,
dialect: db.dialect,
},
);
exports.sequelize = sequelize;
[env] 설명
env 파일을 환경 변수로 읽어오기 위한 코드
\Desktop\Backend code\sequlize_220106\metacamp-backend\models\index.js
const env = process.env.NODE_ENV || 'development' // default 값 'development'
const config = require('../config/config')[env];
여기서 아래 코드의 경우
const config = require('../config/config')[env];
다음과 같다.
const config1 = require('../config/config');
const config = config1['development']
// 혹은
const config1 = require('../config/config');
const config = config1.development
Model
데이터 타입
두 요소를 합쳐서 유니크 만드는 법
ex) 학년+반
/models/department.js
sc_grade: {
type: Sequelize.STRING(50),
unique: school,
},
sc_class: {
type: Sequelize.STRING(50),
unique: school,
},
sequelize 옵션
{
sequelize,
// tableName: 'tableName', // table명을 수동으로 생성 함
// freezeTableName: true, // true: table명의 복수형 변환을 막음
underscored: true, // true: underscored, false: camelCase
timestamps: true, // createAt, updatedAt
paranoid: true, // deletedAt
});
}
};
DB는 대소문자 구별 X
따라서 underscored : true로 자동 변환 해주는 게 좋다.
false : camelCase로는 대소문자 구별이 없어 힘듦
인덱스 파일 생성
const { sequelize } = require('./connection');
const Department = require('./department');
const db = {};
db.sequelize = sequelize;
// model 생성
db.Department = Department;
// model init
Department.init(sequelize);
module.exports = db;
모델 초기화 = 테이블 생성
/app.js
const models = require('./models/index');
const logger = require('./lib/logger');
//...
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// DB 연결 확인 및 table 생성
models.sequelize.authenticate().then(() => {
logger.info('DB connection success');
// sequelize sync (table 생성)
models.sequelize.sync().then(() => {
logger.info('Sequelize sync success');
}).catch((err) => {
logger.error('Sequelize sync error', err);
});
}).catch((err) => {
logger.error('DB Connection fail', err);
});
...
느낀 점
nodejs, express, sequelize까지 쭉쭉 배웠다.
IoT 했다가 웹 했다가 왔다갔다하니까 바뀔 때면 머릿속에서 로딩이 좀 되고 있는데 그래도 이번엔 아예 모르는 게 아니라 로딩이 짧아서 다행이었다.
'공부 > [TIL] Digital Twin Bootcamp' 카테고리의 다른 글
TIL_220126_Backend_CRUD (0) | 2022.01.26 |
---|---|
TIL_220125_Backend_CRUD (0) | 2022.01.25 |
TIL_220121_IOT (0) | 2022.01.21 |
TIL_220120_IOT (0) | 2022.01.20 |
TIL_220119_IOT (0) | 2022.01.19 |