서버(Server)/Server&Nodejs&DB

nodejs : Express 로 연동하여 서버연동과 미들웨어

3DMP 2018. 5. 1. 17:39


Express 로 서버 띄우기




미들웨어 : 구조 내에서 중간 처리를 위한 함수
1)  express 프레임워크에서 사용할 수 있는 중간 처리 목적으로 사용
2) 요청에 대한 응답을 완수하기 전까지 중간중간 다양한 일을 처리할 수 있음
3) 미들웨어 함수 생명주기 : request, response 응답을 주기로 종료 
4) 미들웨어 함수 우선순위 : 먼저 로드되는 미들웨어 함수가 먼저 실행됨(코드 순서 중요)





cmd 를 통해 아래 명령줄을 실행해 설치

npm install express --save


이때 외장모듈과 express 이름과 충돌이 되면 설치가 안될 수 있으니 이름만들때 주의




http 로 서버 실행시키도 대기 시키는 것과 유사한데 다만 express 를 넘겨줘서 


express의 기능들을 사용 할수 있도록 넘겨준다는 점에서 약간 다르다


//웹서버를 app 기반으로 생성
var appServer = http.createServer(app);




아래 구문을 실행한 다음


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var express = require('express');
 
var http = require('http');
 
var app = express();      //express 서버 객체
 
//app 에 임의의 문자열인 port 로 속성을 세팅함
//환경 변수에 PORT 를 설정했다면 그것을 포트로 그렇지 않으면 3000 으로 포트 번호를 express 에 세팅함
app.set('port'3000);
//속성을 set 으로 설정하고 get 으로 가져올 수 있다
 
//웹서버를 app 기반으로 생성
var appServer = http.createServer(app);
 
 
 
appServer.listen(app.get('port'),
    function ()
    {
        console.log('express 웹서버 실행' + app.get('port'));
    }
    
);
 




브라우저에서 localhost:3000  를 입력했을때의 결과화면





req, res : 에 대한 설명

Request(req

The req object represents the HTTP request and has properties for the request query string, parameters, body, HTTP headers, and so on. In this documentation and by convention, the object is always referred to as req (and the HTTP response is res) but its actual name is determined by the parameters to the callback function in which you’re working.

For example:

app.get('/user/:id', function(req, res) {
  res.send('user ' + req.params.id);
});

But you could just as well have:

app.get('/user/:id', function(request, response) {
  response.send('user ' + request.params.id);
});

The req object is an enhanced version of Node’s own request object and supports all built-in fields and methods.






Response(res)

The res object represents the HTTP response that an Express app sends when it gets an HTTP request.

In this documentation and by convention, the object is always referred to as res (and the HTTP request is req) but its actual name is determined by the parameters to the callback function in which you’re working.

For example:

app.get('/user/:id', function(req, res){
  res.send('user ' + req.params.id);
});

But you could just as well have:

app.get('/user/:id', function(request, response){
  response.send('user ' + request.params.id);
});









Express 와 미들웨어



express 로 실행 되는 흐름


미들웨어 : 클라이언트로부터 요청이 오면 요청을 가로채 처리하는 것을 말함


 즉 여러개의 미들웨어가 있을 수 있음 다음 미들웨어는 next()를 실행해야 다음 미들웨어를 받을 수 있음


미들웨어 등록은 use() 로 설정한다



요청패스 URL 에 따라 다른 함수가 실행되게 만들려면 라우터를 통해서 처리한다


처리 방식은 / 도는  /users 로 요청하여 다른 함수가 실행 될 수 있도록 만들 수 있다







실행 흐름

  1. 웹서버를 실행시킨다

  2. 클라이언트에서 3000 포트로 요청을 한다

  3. 서버의 미들웨어가 요청을 받아 미들웨어의 함수로 처리한다( 클라이언트로 바로 응답을 보낼 수도 있다)

  4. 클라이언트는 요청의한 결과를 화면에 뿌려준다



Express + middleware 로 클라이언트 요청에 의한 함수 실행 시키기


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
37
38
39
40
41
42
var express = require('express');
 
var http = require('http');
 
var app = express();      //express 서버 객체
 
//app 에 임의의 문자열인 port 로 속성을 세팅함
//환경 변수에 PORT 를 설정했다면 그것을 포트로 그렇지 않으면 3000 으로 포트 번호를 express 에 세팅함
app.set('port'3000);
//속성을 set 으로 설정하고 get 으로 가져올 수 있다
 
//미들웨어 등록(미들웨어 == 함수)
app.use(
    //http 에서 제공되는 모듈에서 express 에 필요한것이 추가된 것을 파라미터 req, res 로 전달된다
    //req : request 객체
    //res : response 객체
    function (req, res, next)
    {
        console.log('middle wared was called first');
 
        //바로 응답 보내기 처리
        res.writeHead(200,  //정상 응답
            { "Content-Type""text/html;characterset=utf-8" }    //문서를 html 형과 해당 문자 캐릭터 셋으로 보냅
        );
        res.end('<h1> response from server first </h1>');      // 전송함
 
    }
);
 
 
 
//웹서버를 app 기반으로 생성
var appServer = http.createServer(app);
appServer.listen(app.get('port'),
    function () {
        console.log('express 웹서버 실행' + app.get('port'));
    }
 
);
 
 
 






서버쪽 실행화면 및 대기






브라우저에서 요청 시도 결과


아래 화면은 클라이언트에서 서버로 요청을 시도한 화면이다 (F12 -> 네트워크 에서 확인)






브라우저에서 응답 헤더를 보면 미들웨어에서 클라이언트로 보내줬던 문서 형식 "Content-Type""text/html;characterset=utf-8" 


이 응답헤더에 있다는 것을 알 수 있다


즉 클라이언트이 요청을 미들웨어가 가로채 대신 처리한다








미들웨어 여러개 처리 흐름













미들웨어 사용

Express는 자체적인 최소한의 기능을 갖춘 라우팅 및 미들웨어 웹 프레임워크이며, Express 애플리케이션은 기본적으로 일련의 미들웨어 함수 호출입니다.

미들웨어 함수는 요청 오브젝트(req), 응답 오브젝트 (res), 그리고 애플리케이션의 요청-응답 주기 중 그 다음의 미들웨어 함수 대한 액세스 권한을 갖는 함수입니다. 그 다음의 미들웨어 함수는 일반적으로 next라는 이름의 변수로 표시됩니다.

미들웨어 함수는 다음과 같은 태스크를 수행할 수 있습니다.

  • 모든 코드를 실행.
  • 요청 및 응답 오브젝트에 대한 변경을 실행.
  • 요청-응답 주기를 종료.
  • 스택 내의 그 다음 미들웨어 함수를 호출.

현재의 미들웨어 함수가 요청-응답 주기를 종료하지 않는 경우에는 next()를 호출하여 그 다음 미들웨어 함수에 제어를 전달해야 합니다. 그렇지 않으면 해당 요청은 정지된 채로 방치됩니다.

Express 애플리케이션은 다음과 같은 유형의 미들웨어를 사용할 수 있습니다.

애플리케이션 레벨 및 라우터 레벨 미들웨어는 선택적인 마운트 경로를 통해 로드할 수 있습니다. 일련의 미들웨어 함수를 함께 로드할 수도 있으며, 이를 통해 하나의 마운트 위치에 미들웨어 시스템의 하위 스택을 작성할 수 있습니다.

애플리케이션 레벨 미들웨어

app.use() 및 app.METHOD() 함수를 이용해 애플리케이션 미들웨어를 앱 오브젝트의 인스턴스에 바인드하십시오. 이때 METHOD는 미들웨어 함수가 처리하는 요청(GET, PUT 또는 POST 등)의 소문자로 된 HTTP 메소드입니다.

다음 예에는 마운트 경로가 없는 미들웨어 함수가 표시되어 있습니다. 이 함수는 앱이 요청을 수신할 때마다 실행됩니다.


var app = express();

app.use(function (req, res, next) {
  console.log('Time:', Date.now());
  next();
});

다음 예에는 /user/:id 경로에 마운트되는 미들웨어 함수가 표시되어 있습니다. 이 함수는 /user/:id 경로에 대한 모든 유형의 HTTP 요청에 대해 실행됩니다.


app.use('/user/:id', function (req, res, next) {
  console.log('Request Type:', req.method);
  next();
});

다음 예에는 라우트 및 해당 라우트의 핸들러 함수(미들웨어 시스템)이 표시되어 있습니다. 이 함수는 /user/:id 경로에 대한 GET 요청을 처리합니다.


app.get('/user/:id', function (req, res, next) {
  res.send('USER');
});

아래에는 하나의 마운트 경로를 통해 일련의 미들웨어 함수를 하나의 마운트 위치에 로드하는 예가 표시되어 있습니다. 이 예는 /user/:id 경로에 대한 모든 유형의 HTTP 요청에 대한 요청 정보를 인쇄하는 미들웨어 하위 스택을 나타냅니다.


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();
});

라우트 핸들러를 이용하면 하나의 경로에 대해 여러 라우트를 정의할 수 있습니다. 아래의 예에서는 /user/:id 경로에 대한 GET 요청에 대해 2개의 라우트를 정의합니다. 두 번째 라우트는 어떠한 문제도 발생키지 않지만, 첫 번째 라우트가 요청-응답 주기를 종료시키므로 두 번째 라우트는 절대로 호출되지 않습니다.

다음 예에는 /user/:id 경로에 대한 GET 요청을 처리하는 미들웨어 하위 스택이 표시되어 있습니다.


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('route')를 호출하여 제어를 그 다음 라우트로 전달하십시오. 참고next('route')는 app.METHOD() 또는 router.METHOD() 함수를 이용해 로드된 미들웨어 함수에서만 작동합니다.

*use 함수에서 next('route')를 쓰면 다음 use 문으로 가는 것이 아니고 next()와 동일하게 다음 스택 미들웨어 함수로 간다


(app.use() 및 app.METHOD() 함수를 이용해 애플리케이션 미들웨어를 앱 오브젝트의 인스턴스에 바인드하십시오. 이때 METHOD는 미들웨어 함수가 처리하는 요청(GET, PUT 또는 POST 등)의 소문자로 된 HTTP 메소드입니다.)

다음 예에는 /user/:id 경로에 대한 GET 요청을 처리하는 미들웨어 하위 스택이 표시되어 있습니다.


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'); // 이게 호출되면 다음 app.get('user/:id, 쪽으로 뛴다
  // otherwise pass the control to the next middleware function in this stack
  else next(); //
}, function (req, res, next) {
  // render a regular page
  res.render('regular');
});

// handler for the /user/:id path, which renders a special page
app.get('/user/:id', function (req, res, next) {    // 
  res.render('special');
});

라우터 레벨 미들웨어

라우터 레벨 미들웨어는 express.Router() 인스턴스에 바인드된다는 점을 제외하면 애플리케이션 레벨 미들웨어와 동일한 방식으로 작동합니다.


var router = express.Router();

router.use() 및 router.METHOD() 함수를 사용하여 라우터 레벨 미들웨어를 로드하십시오.

다음 예의 코드는 위에서 애플리케이션 레벨 미들웨어에 대해 표시된 미들웨어 시스템을 라우터 레벨 미들웨어를 사용하여 복제합니다.


var app = express();
var router = express.Router();

// a middleware function with no mount path. This code is executed for every request to the router
router.use(function (req, res, next) {
  console.log('Time:', Date.now());
  next();
});

// a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path
router.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();
});

// a middleware sub-stack that handles GET requests to the /user/:id path
router.get('/user/:id', function (req, res, next) {
  // if the user ID is 0, skip to the next router
  if (req.params.id == 0) next('route');
  // otherwise pass control to the next middleware function in this stack
  else next(); //
}, function (req, res, next) {
  // render a regular page
  res.render('regular');
});

// handler for the /user/:id path, which renders a special page
router.get('/user/:id', function (req, res, next) {
  console.log(req.params.id);
  res.render('special');
});

// mount the router on the app
app.use('/', router);

오류 처리 미들웨어

오류 처리 미들웨어에는 항상 4개의 인수가 필요합니다. 어떠한 함수를 오류 처리 미들웨어 함수로 식별하려면 4개의 인수를 제공해야 합니다. next 오브젝트를 사용할 필요는 없지만, 시그니처를 유지하기 위해 해당 오브젝트를 지정해야 합니다. 그렇지 않으면 next 오브젝트는 일반적인 미들웨어로 해석되어 오류 처리에 실패하게 됩니다.

다른 미들웨어 함수와 동일반 방법으로 다음과 같이 오류 처리 미들웨어 함수를 정의할 수 있지만, 오류 처리 함수는 3개가 아닌 4개의 인수, 구체적으로 말하면 (err, req, res, next) 시그니처를 갖는다는 점이 다릅니다.


app.use(function(err, req, res, next) {
  console.error(err.stack);
  res.status(500).send('Something broke!');
});

오류 처리 미들웨어에 대한 상세 정보는 오류 처리를 참조하십시오.

기본 제공 미들웨어

4.x 버전 이후의 Express는 더 이상 Connect에 종속되지 않습니다. express.static의 실행을 제외하면, 이전에 Express와 함께 포함되었던 모든 미들웨어 함수는 이제 별도의 모듈에 포함되어 있습니다. 미들웨어 함수 목록을 확인하십시오.

express.static(root, [options])

Express의 유일한 기본 제공 미들웨어 함수는 express.static입니다. 이 함수는 serve-static을 기반으로 하며, Express 애플리케이션의 정적 자산을 제공하는 역할을 합니다.

root 인수는 정적 자산의 제공을 시작하는 위치가 되는 루트 디렉토리를 지정합니다.

선택사항인 options 오브젝트는 다음과 같은 특성을 가질 수 있습니다.

특성설명유형기본값
dotfilesdotfile을 제공하기 위한 옵션입니다. 사용 가능한 값은 “allow”, “deny” 및 “ignore”입니다.문자열“ignore”
etagetag의 생성을 사용 또는 사용 안함으로 설정합니다.부울true
extensions파일 확장자 폴백을 설정합니다.배열[]
index디렉토리 인덱스 파일을 전송합니다. 디렉토리 인덱스 작성을 사용하지 않으려면 false를 설정하십시오.혼합“index.html”
lastModifiedOS에서 해당 파일이 마지막으로 수정된 날짜를 Last-Modified 헤더에 설정합니다. 사용 가능한 값은 true 또는 false입니다.부울true
maxAge밀리초 또는 ms 형식의 문자열로 Cache-Control 헤더의 max-age 특성을 설정합니다.숫자0
redirect경로 이름이 디렉토리인 경우 후미부의 “/”로 경로를 재지정합니다.부울true
setHeaders파일을 제공하도록 HTTP 헤더를 설정하기 위한 함수입니다.함수 

아래에는 상세한 옵션 오브젝트와 함께 express.static 미들웨어 함수를 사용하는 예가 표시되어 있습니다.


var options = {
  dotfiles: 'ignore',
  etag: false,
  extensions: ['htm', 'html'],
  index: false,
  maxAge: '1d',
  redirect: false,
  setHeaders: function (res, path, stat) {
    res.set('x-timestamp', Date.now());
  }
}

app.use(express.static('public', options));

다음과 같이, 하나의 앱은 2개 이상의 정적 디렉토리를 가질 수 있습니다.


app.use(express.static('public'));
app.use(express.static('uploads'));
app.use(express.static('files'));

serve-static 함수 및 그 옵션에 대한 자세한 정보는 serve-static 문서를 참조하십시오.

써드파티 미들웨어

Express 앱에 기능을 추가하려면 써드파티 미들웨어를 사용하십시오.

필요한 기능을 위한 Node.js 모듈을 설치한 후, 애플리케이션 레벨 또는 라우터 레벨에서 해당 모듈을 앱에 로드하십시오.

다음 예는 쿠키 구문 분석 미들웨어 함수인 cookie-parser의 설치 및 로드를 나타냅니다.


$ npm install cookie-parser


var express = require('express');
var app = express();
var cookieParser = require('cookie-parser');

// load the cookie-parsing middleware
app.use(cookieParser());

Express와 함께 일반적으로 사용되고 있는 써드파티 미들웨어 함수의 일부 목록을 확인하려면 써드파티 미들웨어를 참조하십시오.


ref : http://expressjs.com/ko/guide/using-middleware.html

반응형