오늘의 목표 : HTTP 모듈로 작성했던 서버를, 프레임워크 Express로 리팩토링 해 보기.
1. Express 설치
// 작업 디렉토리 설정
$ mkdir myapp
$ cd myapp
// package.json 파일 작성
$ npm init
// 어플리케이션 이름과 버전 확인 , 기본 파일 이름 입력( 엔터 )
entry point: (index.js)
// 해당 작업 디렉토리에 Express 설치 후 종속 항목 목록에 저장.
$ npm install express --save
-> Express 간단 사용
// 'Hello World!'응답을 받을 수 있음
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
// 앱 실행
$ node app.js
// 브라우저 : http://localhost:3000/
2. Express의 특징
-> Express는 프레임워크 자체에서 라우터 기능을 제공함.
라우팅 : 메서드와 url ( /upper, /lower 등 ) 에 따라 분기점을 만드는 것.
// 구조
app.METHOD(PATH, HANDLER)
/*
app : express의 인스턴스.
METHOD : HTTP 요청 메소드.
PATH : 서버에서의 경로.
HANDLER : 라우트가 일치할 때 실행되는 핸들러 함수.
*/
: 해당 예시 :
// ex1. 홈 페이지에서 Hello World!로 응답:
app.get('/', function (req, res) {
res.send('Hello World!');
});
// ex2. 애플리케이션의 홈 페이지인 루트 라우트(/)에서 POST 요청에 응답:
app.post('/', function (req, res) {
res.send('Got a POST request');
});
// ex3. /user 라우트에 대한 PUT 요청에 응답:
app.put('/user', function (req, res) {
res.send('Got a PUT request at /user');
});
// ex4. /user 라우트에 대한 DELETE 요청에 응답:
app.delete('/user', function (req, res) {
res.send('Got a DELETE request at /user');
});
: Node.js와의 비교
// 1. Node.js
const requestHandler = (req, res) => {
if(req.url === '/lower') {
if (req.method === 'GET')
{
res.end(data)
}
else if (req.method === 'POST')
{
req.on('data', (req, res) =>
{
// do something ...
})
}
}
}
// 2.Express : 조금 더 직관적이다!
const router = express.Router()
router.get('/lower', (req, res) => {
res.send(data);
})
router.post('/lower', (req, res) => {
// do something
})
-> 미들웨어가 있음.! : 요청에 필요한 기능을 더 할 때 사용.
case 1: POST 요청 등에 포함된 body(payload)를 구조화 할 때
// 기존 Node.js의 HTTP요청을 받는 코드
let body = [];
request.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
// body 변수에는 문자열 형태로 payload가 담겨져 있습니다.
});
-> body를 받기 위해 Buffer를 조합 해야 했음.
->
// npm install body-parser
const bodyParser = require('body-parser');
const jsonParser = bodyParser.json();
// 생략
app.post('/users', jsonParser, function (req, res) {
})
or
// Express v4.16.0 이후에는 express.json()을 사용
const jsonParser = express.json(/*에러 날 시 {strict: false} 추가*/);
// 생략
app.post('/api/users', jsonParser, function (req, res) {
})
case 2: 모든 요청/응답에 CORS 헤더를 붙일 때
// 기존 Node.js에 CORS 를 적용하는 예시
const defaultCorsHeader = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Accept',
'Access-Control-Max-Age': 10
};
// 생략
if (req.method === 'OPTIONS') {
res.writeHead(200, defaultCorsHeader);
res.end()
}
->
// npm install cors 해당 디렉토리에 설치
const cors = require('cors');
// 1. 모든 요청에 대해 CORS 허용
app.use(cors());
// 2. 특정 요청에 대해 CORS 허용.
app.get('/products/:id', cors(), function (req, res, next) {
res.json({msg: 'This is CORS-enabled for a Single Route'})
})
case 3: 모든 요청에 대해 url이나 메서드를 확인할 때
const express = require('express');
const app = express();
const myLogger = function (req, res, next) {
console.log(`http request method is ${req.method}, url is ${req.url}`);
next();
};
app.use(myLogger);
app.get('/', function (req, res) {
res.send('Hello World!');
});
app.listen(3000);
case 4: 요청 헤더에 사용자 인증 정보가 담겨있는지 확인할 때
app.use((req, res, next) => {
// 토큰이 있는 경우에만 성공, 아니면 에러나는 미들웨어
if(req.headers.token){
req.isLoggedIn = true;
next();
} else {
res.status(400).send('invalid user')
}
})
'프론트엔드 블로깅 챌린지 > FE' 카테고리의 다른 글
SEB_FE_ 블로깅 챌린지 _ 39일차 ( 복습 & 기술 면접 준비 ) (0) | 2023.04.10 |
---|---|
SEB_FE_ 블로깅 챌린지 _ 38일차 ( req.query , req.params ) (0) | 2023.04.06 |
SEB_FE_ 블로깅 챌린지 _ 36일차 ( web server - cors 리뷰 ) (0) | 2023.04.04 |
SEB_FE_ 블로깅 챌린지 _ 35일차 ( Effect Hook ) (0) | 2023.04.03 |
SEB_FE_ 블로깅 챌린지 _ 34일차 ( React 데이터 흐름) (0) | 2023.03.31 |