혹시나 잘못된 개념 전달이 있다면 댓글 부탁드립니다. 저의 성장의 도움이 됩니다
Node.js로 웹 서버, API 서버를 제작하기 위해 사용되는 프레임워크
설치 후 사용
npm install express
const express = require('express')
const app = express()
const port = 3000
// HTTP method가 GET이고, Endpoint가 '/' 일 경우
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
요청 메서드와 Endpoint 경로에 따라 수행되는 작업을 나누는 과정
app.METHOD(PATH, HANDLER)
// app : express의 인스턴스
// METHOD : 요청의 HTTP 메서드
// PATH : 서버의 경로 Endpoint
// HANDLER : METHOD와 Endpoint가 일치할 경우 실행되는 함수(=라우트 핸들러)
// 함수의 기본 전달인자는 request, response
// 추가로 next를 전달(콜백함수)할 경우 METHOD의 전달인자로 next에 해당하는 함수를 추가
app.METHOD(PATH, MIDDLEWARE, HANDLER)
// next() 전달인자에 포함한 경우
app.get('/example/b', function (req, res, next) {
console.log('the response will be sent by the next function ...');
next();
}, function (req, res) {
res.send('Hello from B!');
});
// HTTP method가 POST이고, Endpoint가 '/' 일 경우
app.post('/', function (req, res) {
res.send('Got a POST request');
});
// HTTP method가 DELETE이고, Endpoint가 '/user' 일 경우
app.delete('/user', function (req, res) {
res.send('Got a DELETE request at /user');
});
// 모든 HTTP method에 Endpoint가 '/secret' 일 경우
app.all('/secret', function (req, res, next) {
console.log('Accessing the secret section ...');
next(); // pass control to the next handler
});
express.Router클래스를 통해 모듈식으로 사용할 수 있는 핸들러 설정 가능
-> 미들웨어
// birds.js 파일
var express = require('express');
var router = express.Router();
// middleware that is specific to this router
router.use(function timeLog(req, res, next) {
console.log('Time: ', Date.now());
next();
});
router.get('/', function(req, res) {
res.send('Birds home page');
});
router.get('/about', function(req, res) {
res.send('About birds');
});
module.exports = router;
// birds.js 파일에 설정한 router를 다른 파일에서 사용
var birds = require('./birds');
...
app.use('/birds', birds);
Middleware
request 객체와 response 객체를 전달받아 개발자가 의도한 작업을 하기 전에 특정한 작업을 수행하는 함수
ex. POST요청에서 body를 파싱하는 작업을 수행 -> body-parser 미들웨어
POST 요청 등에 포함된 body를 사용할 수 있도록 파싱
-> 파싱 후, 함수 내부에서 req.body
로 body를 이용할 수 있음
body-parser (서드파티 미들웨어)
npm install body-parser
require('body-parser')
const bodyParser = require('body-parser');
const jsonParser = bodyParser.json();
app.post('/users', jsonParser, function (req, res) {/* 생략 */})
⭐️ express.json()
: body를 json으로 변환하여 반환하는 함수
기존의 body-parser 기능을 하는 미들웨어가 express의 내장 미들웨어 함수로 대체되어 사용 가능
express.json(options);
// options : 파싱의 조건 명시(생략 가능 -> 배열이나 객체만 파싱 가능)
express.json({ strict : false });
// 파싱할 대상이 배열이나 객체가 아닐 경우도 파싱 가능하게 설정
// 설치 할 필요없이 바로 사용 가능
const jsonParser = express.json();
app.post('/users', jsonParser, function (req, res) {/* 생략 */})
// Node.js만을 사용한 동일한 작업 비교용
let body = [];
request.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
/* 생략 */
});
cors (서드파티 미들웨어)
: 모든 요청에 CORS를 적용할 수 있는 미들웨어
-> 기존 Node.js로 작업시 라우팅마다 헤더를 수정해줘야하는 번거로움을 한번에 해결 가능
설치 : npm install cors
호출 : require('cors')
const cors = require('cors');
// 모든 요청에 CORS 허용
app.use(cors());
// 특정 요청에 CORS 허용
app.get('/products/:id', cors(), function (req, res, next) {
res.json({msg: 'This is CORS-enabled for a Single Route'})
})
// Node.js만을 사용한 동일한 작업 비교용
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(201, defaultCorsHeader); // <--- CORS 허용을 위해 헤더 설정
res.end()
}
-> 직접 미들웨어를 작성하여 사용
app.METHOD()
( METHOD는 요청의 HTTP 메서드 )app.use()
next()
를 추가하여 다음 작업이 실행되게 설정logger 미들웨어 만들기
const express = require('express');
const app = express();
// logger 미들웨어 생성
const myLogger = function (req, res, next) {
console.log(`http request method is ${req.method}, Endpoint is ${req.url}`);
next();
};
// app.use(myLogger); // <--- 모든 요청에 적용
// app.get('/', function (req, res) {
// res.send('Hello World!');
// });
app.get('/', myLogger, function (req, res) { // <--- 특정 요청에 미들웨어 적용
res.send('Hello World!');
});
app.listen(3000);
-> 직접 미들웨어를 작성하여 사용
// 모든 요청에 토큰이 있는 경우만 다음 콜백함수 실행
// ex. 로그인을 하지 않았다면 미들웨어가 요청한 작업 수행을 못하게 막음
app.use((req, res, next) => {
if(req.headers.token){
req.isLoggedIn = true;
next();
} else {
res.status(400).send('invalid user')
}
});
content-type
헤더를 입력받은 데이터에 맞게 적용하여 전달content-type
헤더를 application/JSON
으로 적용하여 전달// json 형태로 응답
res.send(JSON.stringify(req.body));
res.json(req.body);
res.end()
res.status(404).end()
GET 메서드의 경우 payload 대신 URI의 query parameter, path parameter로 필요한 리소스 전달
GET /39th?age=25
-> 특정한 조건으로 필터링req.query
-> { age : "25" }
GET /people/49
-> id가 49인 대상 지목/:id
req.params
-> { id : "49" }
개선점 및 리마인드
**