미들웨어
- 미들웨어는 누군가 미리 만들어 놓은 코드를 부품을 쓰듯이 생산성을 높이기 위하여 쓸 수 있는 기능이라고 말할 수 있다.
- express 자체가 미들웨어로 구성되어있다고 해도 무방하다.
미들웨어 사용하기
body-praser라는 node.js 코드를 더 간결하고 간단하게 해주는 미들웨이로 예를 들어 보겠다.
expressjs.com/en/resources/middleware/body-parser.html
Express body-parser middleware
body-parser Node.js body parsing middleware. Parse incoming request bodies in a middleware before your handlers, available under the req.body property. Note As req.body’s shape is based on user-controlled input, all properties and values in this object a
expressjs.com
npm install body-parser
위의 코드를 터미널에서 명령하면 body-parser라는 미들웨어가 깔린다.
var bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({ extended: false }))
위 두 코드를 추가시켜줘야 main.js안에서 body-parser 미들웨이가 작동한다.
body-parser 적용 예시
const express = require('express')
const app = express()
const port = 3000
var fs = require('fs');
var qs = require('querystring');
var template = require('./lib/template.js');
var path = require('path');
var sanitizeHtml = require('sanitize-html');
var bodyParser = require('body-parser') //추가
app.use(bodyParser.urlencoded({ extended: false })) //추가
app.get('/', (request, response) => {
fs.readdir('./data', function(error, filelist){
var title = 'Welcome';
var description = 'Hello, Node.js';
var list = template.list(filelist);
var html = template.HTML(title, list,
`<h2>${title}</h2>${description}`,
`<a href="/create">create</a>`
);
response.send(html);
});
});
app.get('/page/:pageId',(request, response)=>{
fs.readdir('./data', function(error, filelist){
var filteredId = path.parse(request.params.pageId).base;
fs.readFile(`data/${filteredId}`, 'utf8', function(err, description){
var title = request.params.pageId;
var sanitizedTitle = sanitizeHtml(title);
var sanitizedDescription = sanitizeHtml(description, {
allowedTags:['h1']
});
var list = template.list(filelist);
var html = template.HTML(sanitizedTitle, list,
`<h2>${sanitizedTitle}</h2>${sanitizedDescription}`,
` <a href="/create">create</a>
<a href="/update/${sanitizedTitle}">update</a>
<form action="/delete_process" method="post">
<input type="hidden" name="id" value="${sanitizedTitle}">
<input type="submit" value="delete">
</form>`
);
response.send(html);
});
});
})
app.get('/create', (request, response)=>{
fs.readdir('./data', function(error, filelist){
var title = 'WEB - create';
var list = template.list(filelist);
var html = template.HTML(title, list, `
<form action="/create_process" method="post">
<p><input type="text" name="title" placeholder="title"></p>
<p>
<textarea name="description" placeholder="description"></textarea>
</p>
<p>
<input type="submit">
</p>
</form>
`, '');
response.send(html);
});
});
//body-parser 때문에 post의 두번째 인자인 콜백함수의 첫번째 인자에는 body라는 프로퍼티가
//자동으로 추가되었다고 생각하면 된다.
app.post('/create_process', (request, response)=>{
//body 프로퍼티를 적용하면 이제 따로 받은 데이터를 받는 코드를 작성하지 않아도 된다.
var post = request.body;
var title = post.title;
var description = post.description;
fs.writeFile(`data/${title}`, description, 'utf8', function(err){
response.writeHead(302, {Location: `/? id=${title}`});
response.end();
});
});
/*var body = '';
request.on('data', function(data){
body = body + data;
});
request.on('end', function(){
var post = qs.parse(body);
var title = post.title;
var description = post.description;
fs.writeFile(`data/${title}`, description, 'utf8', function(err){
response.writeHead(302, {Location: `/?id=${title}`});
response.end();
})
});*/
app.get('/update/:pageId', (request, response)=>{
fs.readdir('./data', function(error, filelist){
var filteredId = path.parse(request.params.pageId).base;
fs.readFile(`data/${filteredId}`, 'utf8', function(err, description){
var title = request.params.pageId;
var list = template.list(filelist);
var html = template.HTML(title, list,
`
<form action="/update_process" method="post">
<input type="hidden" name="id" value="${title}">
<p><input type="text" name="title" placeholder="title" value="${title}"></p>
<p>
<textarea name="description" placeholder="description">${description}</textarea>
</p>
<p>
<input type="submit">
</p>
</form>
`,
`<a href="/create">create</a> <a href="/update?id=${title}">update</a>`
);
response.send(html);
});
});
});
app.post('/update_process', (request, response)=>{
/body 프로퍼티를 적용하면 이제 따로 받은 데이터를 받는 코드를 작성하지 않아도 된다.
var post = request.body;
var id = post.id;
var title = post.title;
var description = post.description;
fs.rename(`data/${id}`, `data/${title}`, function(error){
fs.writeFile(`data/${title}`, description, 'utf8', function(err){
response.redirect(`/?id=${title}`);
})
});
});
/* var body = '';
request.on('data', function(data){
body = body + data;
});
request.on('end', function(){
var post = qs.parse(body);
var id = post.id;
var title = post.title;
var description = post.description;
fs.rename(`data/${id}`, `data/${title}`, function(error){
fs.writeFile(`data/${title}`, description, 'utf8', function(err){
response.redirect(`/?id=${title}`);
*/
app.post('/delete_process', (request, response)=>{
/body 프로퍼티를 적용하면 이제 따로 받은 데이터를 받는 코드를 작성하지 않아도 된다.
var post = request.body;
var id = post.id;
var filteredId = path.parse(id).base;
fs.unlink(`data/${filteredId}`, function(error){
response.redirect('/');
});
});
/* var body = '';
request.on('data', function(data){
body = body + data;
});
request.on('end', function(){
var post = qs.parse(body);
var id = post.id;
var filteredId = path.parse(id).base;
fs.unlink(`data/${filteredId}`, function(error){
response.redirect('/');
*/
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
미들웨어 만들기
main.js
const express = require('express')
const app = express()
const port = 3000
var fs = require('fs');
var qs = require('querystring');
var template = require('./lib/template.js');
var path = require('path');
var sanitizeHtml = require('sanitize-html');
var bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({ extended: false }))
//아래와 같이 미들웨어를 만들 수 있다. 지금까지 반복되었던
//"fs.readdir('./data', function(error, filelist){"을 미들웨어로 만들어 코드를 축약시켰다.
//'*'는 이 파일 안에 있는 코드 전체에 적용시킨다는 의미이다.
app.get('*', function(request, response, next){
fs.readdir('./data', function(error, filelist){
//읽어온 데이터를 받은 콜백함수 두번째 인자의 filelis을 request.list로 변수화
//여기서 request.list의 request는 app.get 미들웨이의 함수인 request 객체를 인자로
//받은 파라미터라고 보면된다.
request.list = filelist;
next(); //next 파라미터에는 그 다음에 호출될 미들웨어를 담고있으므로 꼭 실행시켜줘야한다.
});
});
app.get('/', (request, response) => {
var title = 'Welcome';
var description = 'Hello, Node.js';
var list = template.list(request.list); //request.list로 변환
var html = template.HTML(title, list,
`<h2>${title}</h2>${description}`,
`<a href="/create">create</a>`
);
response.send(html);
});
app.get('/page/:pageId',(request, response)=>{
var filteredId = path.parse(request.params.pageId).base;
fs.readFile(`data/${filteredId}`, 'utf8', function(err, description){
var title = request.params.pageId;
var sanitizedTitle = sanitizeHtml(title);
var sanitizedDescription = sanitizeHtml(description, {
allowedTags:['h1']
});
var list = template.list(request.list); //request.list로 변환
var html = template.HTML(sanitizedTitle, list,
`<h2>${sanitizedTitle}</h2>${sanitizedDescription}`,
` <a href="/create">create</a>
<a href="/update/${sanitizedTitle}">update</a>
<form action="/delete_process" method="post">
<input type="hidden" name="id" value="${sanitizedTitle}">
<input type="submit" value="delete">
</form>`
);
response.send(html);
});
});
app.get('/create', (request, response)=>{
var title = 'WEB - create';
var list = template.list(request.list); //request.list로 변환
var html = template.HTML(title, list, `
<form action="/create_process" method="post">
<p><input type="text" name="title" placeholder="title"></p>
<p>
<textarea name="description" placeholder="description"></textarea>
</p>
<p>
<input type="submit">
</p>
</form>
`, '');
response.send(html);
});
app.post('/create_process', (request, response)=>{
var post = request.body;
var title = post.title;
var description = post.description;
fs.writeFile(`data/${title}`, description, 'utf8', function(err){
response.writeHead(302, {Location: `/? id=${title}`});
response.end();
});
});
app.get('/update/:pageId', (request, response)=>{
var filteredId = path.parse(request.params.pageId).base;
fs.readFile(`data/${filteredId}`, 'utf8', function(err, description){
var title = request.params.pageId;
var list = template.list(request.list); //request.list로 변환
var html = template.HTML(title, list,
`
<form action="/update_process" method="post">
<input type="hidden" name="id" value="${title}">
<p><input type="text" name="title" placeholder="title" value="${title}"></p>
<p>
<textarea name="description" placeholder="description">${description}</textarea>
</p>
<p>
<input type="submit">
</p>
</form>
`,
`<a href="/create">create</a> <a href="/update?id=${title}">update</a>`
);
response.send(html);
});
});
app.post('/update_process', (request, response)=>{
var post = request.body;
var id = post.id;
var title = post.title;
var description = post.description;
fs.rename(`data/${id}`, `data/${title}`, function(error){
fs.writeFile(`data/${title}`, description, 'utf8', function(err){
response.redirect(`/?id=${title}`);
})
});
});
app.post('/delete_process', (request, response)=>{
var post = request.body;
var id = post.id;
var filteredId = path.parse(id).base;
fs.unlink(`data/${filteredId}`, function(error){
response.redirect('/');
});
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
미들웨어의 실행순서
app.use('/user/:id', function (req, res, next) {
console.log('Request URL:', req.originalUrl)
next()
}, function (req, res, next) {
console.log('Request Type:', req.method)
next()
})
위와 같이 미들웨어를 여러개를 붙일 수 있다.
app.get('/user/:id', function (req, res, next) {
console.log('ID:', req.params.id)
next()
}, function (req, res, next) {
res.send('User Info')
})
// handler for the /user/:id path, which prints the user ID
app.get('/user/:id', function (req, res, next) {
res.end(req.params.id)
})
next()을 호출하게 되면 계속 미들웨어를 붙일 수 있지만 호출하지 않는다면 거기서 미들웨이는 끝나게 된다고 볼 수 있따.
app.get('/user/:id', function (req, res, next) {
// if the user ID is 0, skip to the next route
if (req.params.id === '0') next('route')
// otherwise pass the control to the next middleware function in this stack
else next()
}, function (req, res, next) {
// send a regular response
res.send('regular')
})
// handler for the /user/:id path, which sends a special response
app.get('/user/:id', function (req, res, next) {
res.send('special')
})
위와 같은 조건문 if을 주어 다음 미들웨어를 이어나갈지 안나갈지 정해줄 수도 있다.
'프로그래밍 개발 > Express' 카테고리의 다른 글
Express - 라우터의 파일로 분리 정리 (0) | 2021.01.14 |
---|---|
Express - 에러처리 (0) | 2021.01.14 |
Express - 정적인 파일의 서비스 (0) | 2021.01.14 |
Express - Express 홈페이지 구현 적용 (0) | 2021.01.14 |
Express - 기본 세팅 시작 (0) | 2021.01.14 |
댓글