Juni_Dev_log

(node.js) [Part.5] 웹 서버 만들기 - 미들웨어 사용하기 본문

Theorem (정리)/node.js

(node.js) [Part.5] 웹 서버 만들기 - 미들웨어 사용하기

Juni_K 2020. 12. 8. 21:01

use() 메소드로 설정하는 미들웨어 함수 안에 코드를 직접 넣어 클라이언트로 응답을 전송해보았다.

그런데 웹 서버를 다루기 위해 필요한 모든 기능을 우리가 직접 미들웨어로 만들어야 하면, 실무에서 사용할 수 있는 웹 서버를 구성하는 것이 쉽지 않을 것이다.

익스프레스에서는 개발자가 다양한 기능을 사용할 수 있도록 미리 만들어 둔 여러 가지 미들웨어를 제공한다.

특히, 다른 개발자들이 만들어서 올려 둔 미들웨어를 쉽게 끼워 넣을 수 있어서 아주 편리하게 사용할 수 있다.

기본적인 몇 가지 미들웨어에 대해서 알아보자.

static 미들웨어

먼저 static 미들웨어는 특정 폴더의 파일들을 특정 패스로 접근할 수 있도록 만들어준다.

예를 들어, [public] 폴더에 있는 모든 파일을 웹 서버의 루트 패스로 접근할 수 있도록 만들고 싶다면 다음 코드를 추가하면 된다.

var static = require('serve-static');
...
app.use('/public', static(path.join(__dirname, 'public')));

static 미들웨어는 외장 모듈로 만들어져 있어서 설치가 필요하다.

명령 프롬프트에서 아래에 코드를 이용해서 설치한다.

 

npm install serve-static --save

 

이 코드는 [public] 폴더 안에 있는 파일들을 클라이언트에서 바로 접근할 수 있게 한다. 프로젝트 폴더 안에 다음과 같은 폴더나 파일들이 들어 있다면,

 

ExpressExample/public/index.html
ExpressExample/public/images/house.png
ExpressExample/public/js/main.js
ExpressExample/public/css/style.css

웹 브라우저에서 다음과 같은 주소로 바로 접근할 수 있다.

 

http://localhost:3000/index.html
http://localhost:3000/images/house.png
http://localhost:3000/js/main.js
http://localhost:3000/css/style.css

 

ExpressExample 폴더 안에 새로운 public 파일을 만든다.  그러면, public 폴더에 바로 접근할 수 있다.

만약, ExpressExample 프로젝트 안의 [/public/images] 폴더에 들어 있는 house.png 이미지 파일을 웹 브라우저에서 보려면 app.js 파일 안에서 다음과 같이 응답을 보내면 된다.

 

res.end("<img src='/images/house.png' width='50%'>");

 

만약 public 폴더 안에 있는 파일을 사이트 /public 패스로 접근하도록 만들고 싶다면 static() 메소드를 호출할 때 다음과 같이 패스를 지정하면된다.

 

app.use('/public', static(path.join(__dirname, 'public')));

 

코드가 조금 길어 보이지만 자세히 보면, use() 메소드의 첫 번째 파라미터로 요청패스를 지정했고, 두 번째 파라미터로 static() 함수로 특정 폴더를 지정했다. 이렇게 하면 요청 패스와 특정 폴더가 매핑(Mapping, 서로 연결되는 것)되어 접근할 수 있다.

 

요청 패스와 특정 폴더를 static() 메소드로 매핑하기

body-parser 미들웨어

이번에는 POST 로 요청했을 때, 요청 파라미터를 확인할 수 있도록 만들어 둔 body-parser 미들웨어에 대해 알아보자.

GET 방식으로 요청할 때는 주소 문자열에 요청 파라미터가 들어간다.

 

하지만, 이와 달리 POST 방식으로 요청할 때는 본문인 본문 영역(body)에 요청 파라미터가 들어 있게 되므로 요청 파라미터를 파싱하는 방법이 GET 방식과는 다르다.

 

body-parser 미들웨어는 클라이언트가 POST 방식으로 요청할 때 본문 영역에 들어 있는 요청 파라미터들을 파싱하여 요청 객체의 body 속성에 넣어준다.

웹 브라우저에서 POST 방식으로 요청하여 어떻게 요청 파라미터를 받는지 확인해보자.

먼저, 웹 브라우저에 접속하여 볼 수 있는 간단한 웹 문서를 하나 만든다. 

프로젝트 폴더 안에, public 폴더를 만들고, 폴더 안에 파일 만들기 메뉴를 선택해서 login.html 을 만든다.

 

그리고 form 태그 안에 넣어 버튼을 눌렀을 때, POST 방식으로 웹 서버에 요청한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>로그인 테스트</title>
</head>
<body>
    <h1>로그인</h1>
    <br>
    <form method="post">
        <table>
            <tr>
                <td><label>아이디</label></td>
                <td><input type="text" name="id"></td>
            </tr>
            <tr>
                <td><labeL>비밀번호</labeL></td>
                <td><input type="password" name="password"></td>
            </tr>
        </table>
        <input type="submit" value="전송" name="">    
    </form>
</body>
</html>
cs

이제 app6.js 파일을 복사하여 app7.js 파일을 만들고, POST 방식으로 정보를 요청했을 때 요청 파라미터를 확인할 수 있도록 다음과 같이 입력한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// Express 기본 모듈 불러오기
var express = require('express');
var http = require('http');
var path = require('path');
 
// Express의 미들웨어 불러오기
var bodyParser = require('body-parser');
var static = require('static');
 
// 익스프레스 객체 생성
var app = express();
 
// 기본 속성 설정
app.set('port', process.env.PORT || 3000);
 
// body-parser 를 사용해 application/x-www-form-urlencoded 파싱
app.use(bodyParser.urlencoded({extended:false}));
 
// body-parser 를 사용해 application/json 파싱
app.use(bodyParser.json());
 
app.use('/public'static(path.join(__dirname, 'public')));
 
// 미들웨어에서 파라미터 확인
app.use(function(req,res,next){
    console.log('첫 번째 미들웨어에서 요청을 처리함.');
    
    var paramId = req.body.id || req.query.id;
    var paramPassword = req.body.password || req.query.password;
    
    res.writeHead('200',{'Content-Type':'text/html;charset=utf8'});
    res.write('<h1>Express 서버에서 응답한 결과입니다.</h1>');
    res.write('<div><p>Param id : ' + paramId +  '</p></div>');
    res.write('<div><p>Param password : ' + paramPassword + '</p></div>');
    res.end();
});
cs

하나하나 살펴보자.

 

require() 메소드를 사용해 모듈을 불러오는 부분이 보인다. 다른 것들은 앞에서 다뤘는데 body-parser 모듈을 새로 추가했다. 명령 프롬프트에서 이 모듈을 설치한다.

 

npm install body-parser --save

 

body-parser 모듈을 사용하기 위한 설정은 두 줄이다.

app 객체의 use() 메소드를 사용해 미들웨어를 설정하는데 bodyParser.urlencoded() 메소드를 호출하면서 미들웨어를 설정하면 application/-x-www-form-urlencoded 형식으로 전달된 요청 파라미터를 파싱할 수 있다.

이 형식은 일반적인 요청 파라미터의 형식이다. bodyParser.json() 메소드를 호출하면서 미들웨어를 설정하면 application/json 형식으로 전달된 요청 파라미터를 파싱할 수 있다.

 

이렇게 하면 사용자 요청을 처리하는 미들웨어 안에서 요청 객체의 body 객체 안에 요청 파라미터들이 들어간다. 즉, 다음 코드를 사용해 요청파라미터를 참조할 수 있다.

 

var paramId = req.body.id;

 

그런데 클라이언트에서 요청할 때 GET 방식으로 요청할지, 아니면 POST 방식으로 요청할지 모르는 경우에는 어떻게 해야할까? 두 가지 경우를 모두 고려하기 위해서 다음처럼 두 가지 요청 파라미터를 모두 검사한다.

 

var paramId = req.body.id || req.query.id;

 

이제 웹 서버가 클라이언트 요청을 기다리도록 app7.js 를 실행하고 브라우저에 접속한다.

http://localhost:3000/login.html 주소를 입력해 접속하면 다음 화면처럼 나온다.

 

웹 브라우저에 띄운 로그인 문서

 

 

서버 코드에서 use() 메소드로 설정한 함수는 login.html 문서에 접근할 때는 호출되지않는다.

따라서 처음에는 login.html 문서가 웹 브라우저에 보이며, 버튼을 클릭하여  POST 로 요청했을 때는 use() 메소드로 설정한 함수가 호출되면서 필요한 작업을 수행한다.

 

아이디와 비밀번호를 입력한 후 '전송' 버튼을 누르면 다음화면이 표시된다.

 

[전송] 버튼을 눌러 결과 화면을 본 경우

이제 GET 방식으로 요청했을 때와 마찬가지로 POST 방식으로 요청했을 때도 요청 파라미터를 확인할 수 있게 되었다.

이것이 어떻게 가능한지 이해했다면 노드에서 미들웨어를 사용한다는 것이 얼마나 편리한지 느낄 수 있다.

Comments