Express의 중요한 기능 두 가지
1. Route
2. Middleware
이전에도 말했듯이, Express에서는 처음부터 코드를 작성하지 않고 다른 이가 작성한 소프트웨어를 부품으로 하여 나의 소프트웨어를 만들어간다. 이를 미들웨어라고 한다.
미들웨어 사용
Express 공식 페이지> 미들웨어 사용 을 클릭해보자.
Third-party middleware
: 다른 이들이 만든 미들웨어. 즉, express가 만들지 않은, 비공식적인 미들웨어
여러 가지 유명한 써드파티 미들웨어 리스트
body-parser
많은 미들웨어 중에서 body-parser를 사용해보자.
- body: 웹 브라우저에서 요청한 정보의 본체. 이 본체를 설명하는 데이터를 header라 한다.
즉, 이 본체 데이터를 분석(parser)하여 우리가 필요한 형태의 데이터로 가공해주는 것이 body-parser이다.
//4. create>제출 버튼 클릭 시 페이지
app.post('/create', function(request, response){
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.redirect(`/page/${title}`);
});
});
});
현재 post>create는 글을 생성했을 때, 생성된 데이터를 받아서 데이터를 처리하는 코드이다. 이때 데이터는 post방식으로 처리되기 때문에 get방식과는 다르게 post방식은 데이터의 크기가 클 수 있다. 그래서 var body 변수를 정의하고, 데이터가 추가 될 때마다 request.on('data', 의 function이 호출이 되는데 그 때마다 기존 body 변수에 도착한 data를 추가시켜준다. 그리고 request.on('end' 즉 더이상 데이터가 없다는 이벤트가 발생했을 때, 실체 처리를 해주는 코드이다.
위처럼 코드를 작성해도 되지만, 미들웨어인 body-parser로 작성하게 되면 코드를 더 우아하게 짤 수 있으며, 발생할 문제를 해결해준다.
Middleware installation
npm install body-parser
API
body-parser 설치 후, 다음으로 불러온다.
const bodyParser = require('body-parser');
사용자가 json데이터로 요청을 한다면 아래 코드를 작성하고,
app.use(bodyParser.json());
form데이터의 경우 아래 코드를 작성한다.
app.use(bodyParser.urlencoded({ extended: false }));
app.use에 bodyParser를 호출하게 되면, 속의 코드가 실행되면서 그 결과로 미들웨어가 들어오게 된다. 즉, body-parser가 만들어내는 미들웨어를 표현하는 표현식이다.
이렇게 작성하게 되면, main.js가 실행될 때마다, 즉 사용자가 요청할 때마다 위 코드에 의해 만들어진 미들웨어가 실행된다. 이 미들웨어가 어떻게 생겼는지는 알 필요가 없다. 내부적으로는 사용자가 전송한 post데이터를 분석하여 모든 데이터를 가져온 다음 /create경로에 해당하는 콜백함수를 호출하도록 약속되어 있다. 그리고 호출하면서 첫 번째 인자인 request 파라미터 변수에 (원래는 body라는 property가 없었지만) body-parser 미들웨어가 request에 body property를 만들어준다.
그리고 이를 통해 코드를 아래와 같이 변경할 수 있게 된다.
//4. create>제출 버튼 클릭 시 페이지
app.post('/create', function(request, response){
var post = request.body;
var title = post.title;
var description = post.description;
fs.writeFile(`data/${title}`, description, 'utf8',
function(err) {
response.redirect(`/page/${title}`);
});
});
결론
이전 코드는 난잡했는데, body-parser 미들웨어를 아래 코드를 통해 장착하고 나니
app.use(bodyParser.urlencoded({ extended: false }));
내부적으로 body-parser가 동작하여, create 라우트를 사용할 때 request 객체의 body property에 접근하는 것을 통해 간결한 코드를 작성할 수 있게 된다.
이와 동일하게 post>update와 delete 코드도 변경할 수 있다.
post>update
//6. update>제출 버튼 클릭 시 페이지
app.post('/update', function(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(err){
fs.writeFile(`data/${title}`, description, 'utf8',
function(err) {
response.redirect(`/page/${title}`);
});
});
})
delete
//7. delete 버튼 클릭 시 페이지
app.post('/delete_process', function(request, response){
var post = request.body;
var id = post.id;
var filteredId = path.parse(id).base;
fs.unlink(`data/${filteredId}`, function(error){
response.redirect('/');
});
})
전체 코드
const express = require('express');
const app = express();
const fs = require('fs');
const path = require('path');
const qs = require('querystring');
const sanitizeHtml = require('sanitize-html');
const template = require('./lib/template');
const bodyParser = require('body-parser');
const port = 3000;
app.use(bodyParser.urlencoded({ extended: false }));
// 1. 홈 페이지
// app.get('/', (req, res) => { res.send('Hello World!')})
app.get('/', function(request, response){
fs.readdir('./data', function(err, filelist){
var title = 'Welcome';
var description = 'Hello, Node.js';
var list = template.list(filelist);
var html = template.html(title, list,
`<a href="/create">create</a>`,
`<h2>${title}</h2>${description}`
);
response.send(html);
});
});
// 2. pageId 링크 클릭 시 페이지
app.get('/page/:pageId', function(request, response){
fs.readdir('./data', function(err, 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);
var list = template.list(filelist);
var html = template.html(sanitizedTitle, list,
`<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>
`,
`<h2>${sanitizedTitle}</h2>${sanitizedDescription}`);
response.send(html);
});
});
});
//3. Create 버튼 클릭 시 페이지
app.get('/create', function(request, response){
fs.readdir('./data', function(err, filelist){
var title = 'WEB - create';
var list = template.list(filelist);
var html = template.html(title, list,
'',
`
<form action="/create" 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);
});
});
//4. create>제출 버튼 클릭 시 페이지
app.post('/create', function(request, response){
var post = request.body;
var title = post.title;
var description = post.description;
fs.writeFile(`data/${title}`, description, 'utf8',
function(err) {
response.redirect(`/page/${title}`);
});
});
//5. update 버튼 클릭 시 페이지
app.get('/update/:pageId', function(request, response){
fs.readdir('./data', function(err, 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 부분
`
<form action="/update" 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>
`,
``);
response.send(html);
});
});
});
//6. update>제출 버튼 클릭 시 페이지
app.post('/update', function(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(err){
fs.writeFile(`data/${title}`, description, 'utf8',
function(err) {
response.redirect(`/page/${title}`);
});
});
})
//7. delete 버튼 클릭 시 페이지
app.post('/delete_process', function(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}`))
'Back-End > Node.js' 카테고리의 다른 글
Express - 10. 미들웨어 만들기 (0) | 2020.09.07 |
---|---|
Express - 9.2. 미들웨어의 사용 - compression (0) | 2020.09.06 |
Express - 8. 페이지 삭제 구현 + redirect (0) | 2020.09.06 |
Express - 7. 페이지 수정 구현 (0) | 2020.09.06 |
Express - 6. 페이지 생성 구현 (0) | 2020.09.06 |