6.1 시작
npm init → package.json 생성
//package.json
{
"name": "learn-express",
"version": "0.0.1",
"description": "익스프레스를 배우자",
"main": "app.js",
"scripts": {
"start": "nodemon app" //추가해주기! (app.js를 nodemon으로 실행, 서버 코드에 수정 사항 생길 때마다 서버 자동 재시작)
},
"author": "ZeroCho",
"license": "MIT"
}
express 시작
$ npm i express
$ npm i -D nodemon
서버 역할 app.js
- GET 요청 외에도 POST, PUT, PATCH, DELETE, OPTIONS에 대한 라우터를 위한 app.post, app.put, app.patch. app.delete, app.options 메서드가 존재
//app.js
const express=require('express');
const app=express();
app.set('port',process.env.PORT ||3000); //서버 실행될 포트 설정
//process.env.PORT에 속성값이 있다면 사용하고, 없다면 기본값 3000번 포트 이용
app.get('/',(req,res)=>{ //주소에 대한 GET 요청이 올때 어떤 동작하는지, req: 요청에 관한 정보 객체, res: 응답에 관한 정보 객체
res.send('Hello, Express'); //현재 GET / 요청 시 응답으로 Hello, Express 전송
});
app.listen(app.get('port'),()=>{ //서버 시작!!! 꼭 해야함~~ 중요!
console.log(app.get('port'),'번 포트에서 대기 중');
});
서버 실행 : npm start
6.2 자주 사용하는 미들웨어
app.use
//app.js
const express=require('express');
const app=express();
app.set('port',process.env.PORT ||3000); //서버 실행될 포트 설정
//process.env.PORT에 속성값이 있다면 사용하고, 없다면 기본값 3000번 포트 이용
app.use((req,res,next)=>{ //app.use : 미들웨어 역할, 매개변수 : req,res,next
//next : 다음 미들웨어로 넘어가는 함수, next를 실행하지 않으면 다음 미들웨어 실행X
console.log('모든 요청에 다 실행됨');
next();
});
app.get('/',(req,res,next)=>{ //주소에 대한 GET 요청이 올때 어떤 동작하는지, req: 요청에 관한 정보 객체, res: 응답에 관한 정보 객체
res.send('Hello, Express'); //현재 GET / 요청 시 응답으로 Hello, Express 전송
next();
},(req,res)=>{ //아래 미들웨어로 전달
throw new Error('에러는 에러 처리 미들웨어로 갑니다!');
});
app.use((err,req,res,next)=>{ //에러 처리 미들웨어 매개변수 : err,req,res,next ,모든 매개변수 사용안해도 꼭 4개여야함
console.error(err);
res.status(500).send(err.message); //기본값 : 200, 특별한 경우 아니면 에러 처리 미들웨어는 가장 아래 위치
});
app.listen(app.get('port'),()=>{ //서버 시작!!! 꼭 해야함~~ 중요!
console.log(app.get('port'),'번 포트에서 대기 중');
});
실무 사용 패키지
$ npm i morgan cookie-parser express-session dotenv
body-parser 패키지 설치
$ npm i body-parser
//app.js
const express=require('express');
const morgan=require('morgan'); //요청과 응답에 대한 정보 콘솔에 기록
const cookieParser=require('cookie-parser');
const session=require('express-session');
const dotenv=require('dotenv'); //process.env 관리, .env파일 읽어서 process.env로 만든다
const path=require('path');
const bodyParser = require('body-parser');
dotenv.config();
const app=express();
app.set('port',process.env.PORT || 3000);
app.use(morgan('dev')); //개발 환경 : dev, 배포 환경 : combined
app.use('/',express.static(path.join(__dirname,'public'))); //static : 정적인 파일 제공하는 라우터 역할, app.use('요청 경로', express.static('실제 경로'));
//서버의 폴더 경로와 요청 경로가 다른 문제를 해결함
//body-parser: 요청의 본문에 있는 데이터를 해석해서 req.body 객체로 만들어주는 미들웨어, 보통 폼 데이터나 AJAX 요청의 데이터 처리
//멀티파트(이미지,동영상,파일)데이터 처리 못함, express에서 일부 제공, 버퍼나 텍스트 요청처리하려면 따로 설치 필요
//body-parser 는 내부적으로 스트림 처리해 req.body에 추가된다!!
app.use(express.json()); //json 형식
app.use(express.urlencoded({extended:false})); //URL-encoded형식(폼 전송), extended: false 면 노드의 querystring모듈을 사용해 쿼리스트링 해석, ture면 qs모듈 사용해 쿼리 스트링 해석
app.use(bodyParser.raw());
app.use(bodyParser.text());
app.use(cookieParser(process.env.COOKIE_SECRET));
app.use(session({
resave:false,
saveUninitialized:false,
secret:process.env.COOKIE_SECRET,
cookie:{
httpOnly:true,
secure:false,
},
name:'session-cookie',
}));
app.use((req,res,next)=>{
console.log('모든 요청에 다 실행됩니다.');
next();
});
//.env
COOKIE_SECRETo=cookiesecret
6.2.6 미들웨어 특성 활용
미들웨어는 req, res, next를 매개변수로 갖는 함수(에러 처리 미들웨어만 예외적으로 err, req, res, next를 가집니다)로서 app.use나 app.get, app.post 등으로 장착합니다. 특정한 주소의 요청에만 미들웨어가 실행되게 하려면 첫 번째 인수로 주소를 넣으면 됩니다.
미들웨어 장착 순서에 따라 어떤 미들웨어는 실행되지 않을수도 있음

app.set : 익스프레스에서 전역적으로 사용, 하나의 요청 안에서만 유지되어야 하는 값을 넣기에는 부적절
→ res.local 객체 사용, 하나의 요청 안에서만 유지
미들웨어 안에 미들웨어 넣는 방법 : 기존 미들웨어 기능 확장, 조건문에 따라 다른 미들웨어 처리
- ex) 분기 처리
app.use((req, res, next) => {
if (process.env.NODE_ENV === 'production') {
morgan('combined')(req, res, next);
} else {
morgan('dev')(req, res, next);
}
});
6.2.7 multer
6.3 Router 객체로 라우팅 분리
//routes/index.js
const express=require('express');
const router=express.Router();
//GET / 라우터
router.get('/',(req,res)=>{
res.send('Hello,Express');
});
module.exports=router;
//routes/user.js
const express=require('express');
const router=express.Router();
//GET /user 라우터
router.get('/',(req,res)=>{
res.send('Hello,user');
});
module.exports=router;
//app.js
const express=require('express');
const morgan=require('morgan'); //요청과 응답에 대한 정보 콘솔에 기록
const cookieParser=require('cookie-parser');
const session=require('express-session');
const dotenv=require('dotenv'); //process.env 관리, .env파일 읽어서 process.env로 만든다
const path=require('path');
const bodyParser = require('body-parser');
dotenv.config();
const indexRouter = require('./routes/index');
const userRouter = require('./routes/user');
const app=express();
app.set('port',process.env.PORT || 3000);
//app.js에 연결할 때 주소가 합쳐짐
app.use('/', indexRouter);
app.use('/user', userRouter);
app.use((req, res, next) => {
res.status(404).send('Not Found');
});
app.listen(3000,()=>{ //서버 시작!!! 꼭 해야함~~ 중요!
console.log("서버 시작!")
})
next(’route’), next() : 라우터에 연결된 나머지 미들웨어들 건너뛰고 싶을 때 사용
router.get('/', (req, res, next) => {
next('route');
}, (req, res, next) => {
console.log('실행되지 않습니다');
next();
}, (req, res, next) => {
console.log('실행되지 않습니다');
next();
});
router.get('/', (req, res) => {
console.log('실행됩니다');
res.send('Hello, Express');
});
라우터 주소에 정규표현식을 비롯한 특수한 패턴 사용가능!
→ 라우트 매개변수 패턴
router.get('/user/:id', (req, res) => {
console.log('얘만 실행됩니다.');
});
router.get('/user/like', (req, res) => {
console.log('전혀 실행되지 않습니다.');
});
/users/1 이나 /users/123 등의 요청도 이 라우터가 처리
:id에 해당하는 1이나 123을 조회 가능, req,params 객체안에 들어있음
:id면 req.params.id로 , :type 이면 req.params.type으로 조회 가능!
주의 할점: 일반 라우터보다 뒤에 꼭 위치해야함!!!
주소에 쿼리스트링도 가능 : 쿼리스트링의 키-값 정보는 req.query 객체 안에 들어있음
ex) /users/123?limit=5&skip=10 주소 요청
→ req.params와 req.query : { id: '123' } { limit: '5', skip: '10' }
app.js에서 에러 처리 미들웨어 위에 넣어둔 미들웨는 일치하는 라우터 없을 때 404 상태 코드 응답 역할 → 익스프레스가 자체적으로 404에러 처리해주기는 하지만, 웬만하면 404응답 미들웨어와 에러 처리 미들웨어를 연결하는게 좋음!!
app.use((req, res, next) => {
res.status(404).send('Not Found');
});
주소는 같지만 메서드는 다른 코드가 있을 때, 하나의 덩어리로 묶음
router.route('/abc')
.get((req, res) => {
res.send('GET /abc');
})
.post((req, res) => {
res.send('POST /abc');
});
6.4 req,res 객체 살펴보기
req 객체
res 객체
메서드 체이닝
res
.status(201)
.cookie('test', 'test')
.redirect('/admin');