Express
- 서버 제작에 있어 불편함을 해소하고 편의 기능을 추가한 웹 서버 프레임워크
- http 모듈의 요청과 응답 객체에 추가 기능들을 부여
시작하기
1. package.json 생성
2. express 모듈 설치
$ npm i express
$ npm i -D nodemon
- nodemon
- 서버 코드에 수정 사항이 생길 때마다 서버를 자동으로 재시작
rs
명령어를 통해 수동 재시작 가능
- 개발용으로만 사용하는 것을 권장
실행하기
1. app.js 파일 작성
const express = require('express');
const path = require('path);
const app = express();
app.set('port', process.env.PORT || 3000);
app.get('/', (req, res) => {
res.send('Hello, Express);
res.sendFile(path.join(__dirname, '/index.html'));
});
app.listen(app.get('port'), () => {
console.log(app.get('port'),'번 포트에서 대기 중');
});
2. 서버 실행
$ npm start
3. 서버 접속
미들웨어
- 요청과 응답 중간에 위치
- 라우터와 에러 핸들러 또한 미들웨어의 일종
- 요청과 응답을 조작하여 기능 추가 / 나쁜 요청 걸러내기 기능 수행
사용하기
app.use(미들웨어);
app.use('주소', 미들웨어);
app.get('주소', 미들웨어);
- 매개변수가
req
, res
, next
인 함수
next
: 다음 미들웨어로 넘어가는 함수 (필수)
- next(): 다음 미들웨어로
- next('route'): 다음 라우터로
- next(error): 에러 핸들러로
- 하나의 라우터에 여러 개의 미들웨어 장착 가능
app.get((req, res, next) => {
console.log('GET / 요청에서만 실행');
next();
}, (req, res) => {
throw new Error('에러 처리 미들웨어로');
});
- 에러처리 미들웨어
- 매개변수가
err
, req
, res
, next
인 함수
- 모든 매개변수를 사용하지 않도라도 반드시 4개여야 함
- 에러처리 미들웨어를 직접 연결하지 않아도 기본적으로 익스프레스가 에러처리 하긴 함
- 일반적으로 가장 아래에 위치
app.use((err, req, res, next) => {
console.error(err);
res.status(500).send(err.message);
});
미들웨어 간의 데이터 전달
1. 세선 사용 시, req.session 객체 이용
2. app.set을 이용한 데이터 저장
- express에서 전역적으로 사용
- 요청을 보낸 사용자 개개인의 값을 넣기에 부적절
- 앱 전체의 설정을 공유할 때 사용
3. req 객체 이용
app.use((req, res, next) => {
req.data = '데이터';
next();
}, (req, res, next) => {
console.log(req.data);
next();
});
dotenv
process.env
파일을 관리하기 위한 패키지
.env
파일을 읽어서 process.env
파일로 만듬
- 보안과 설정의 편의를 위해 별도의 파일로 관리
morgan
- 요청과 응답에 대한 정보를 콘솔에 기록
[HTTP 메서드] [주소] [HTTP 상태 코드] [응답 속도] - [응답 바이트]
app.use(morgan('dev'));
static
- 정적인 파일들을 제공하는 라우터 역할
- 기본적으로 express 객체 내에 존재
- 해당 파일이 없는 경우, 내부적으로
next()
호출
- 파일이 있는 경우, 응답으로 파일 보냄(
next()
호출 X)
app.use('/', express.static(path.join(__dirname, 'public')));
body-parser
- 요청의 본문에 있는 데이터를 해석해서
req.body
객체 생성
- 멀티파트(이미지, 동영상, 파일) 데이터는 처리 X ->
multer
모듈 이용
- JSON, URL-encoded 형식 데이터 해석
express 4.16.0
부터 내장되어 있음.
- Raw, Text 형식의 데이터 해석할 경우, 직접 설치 필요
app.use(express.json());
app.use(express.urlencoded({ extended: false });
cookie-parser
- 요청에 동봉된 쿠키를 해석해
req.cookies
객체 생성
- 서명된 쿠키를 통해 해당 쿠키가 내 서버가 만든 쿠키인지 검증
app.use(cookieParser(비밀키));
- 쿠키 생성:
res.cookie(키, 값, 옵션)
- 쿠키 제거:
res.clearCookie
express-session
- 세션 관리용 미들웨어
- 사용자별로
req.session
객체 안에 유지
app.use(session({
resave: false,
saveUninitialized: false,
secret: process.env.COOKIE_SECRET,
cookie: {
httpOnly: true,
secure: false,
},
name: 'session-cookie',
})));
- store 옵션
- 현재와 같이 메모리에 세션을 저장하면, 서버를 재시작할 때 메모리가 초기화 됨
- 배포 시, store에 DB를 연결하여 세션 유지하는 것이 좋음
express-session
에서 서명한 쿠키: s%3A
가 앞에 붙음
라우팅 분리
1. routes 폴더 내 라우터 파일 생성
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.send('index.js');
});
module.exports = router;
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.send('user.js');
});
module.exports = router;
2. app.js에 라우터 연결
const indexRouter = require('./routes');
const userRouter = require('./routes/user');
app.use('/', indexRouter);
app.use('/user', userRouter);
app.use((req, res, next) => {
res.status(404).send('Not Found');
});
라우트 매개변수
req.params
객체 내부에 존재
- 일반 라우터보다 뒤에 위치해야 함
router.get('/user/:id', function(req, res) {
console.log(req.params, req,query);
});
- ex.
/users/123?limit=5&skip=10
-> { id: '123' } { limit: '5', skip: '10' }
하나의 라우터에 여러 메서드 추가하기
router.route('/abc')
.get(...)
.post(...);
템플릿 엔진
- 자바스크립트를 사용해서 HTML을 렌더링
- 퍼그(Pug), 넌적스(Numjucks) 등