[node.js] Expressjs에서 미들웨어 및 app.use는 실제로 무엇을 의미합니까?

내가 본 거의 모든 Express 앱에는 app.use미들웨어에 대한 설명이 있지만 실제로 미들웨어가 무엇이며 app.use명령문이 무엇을하고 있는지에 대한 명확하고 간결한 설명을 찾지 못했습니다 . 표현 문서 자체조차도 약간 모호합니다. 이 개념들을 설명해 주시겠습니까?



답변

미들웨어

나는 새 프로젝트에서 미들웨어 개념을 분리하는 중반 쯤입니다.

미들웨어를 사용하면 처리해야 할 작업 스택을 정의 할 수 있습니다. Express 서버 자체는 미들웨어의 스택입니다.

// express
var app = express();
// middleware
var stack = middleware();

그런 다음 호출하여 미들웨어 스택에 레이어를 추가 할 수 있습니다 .use

// express
app.use(express.static(..));
// middleware
stack.use(function(data, next) {
  next();
});

미들웨어 스택의 계층은 함수이며, n 개의 매개 변수 (표현식 req&에 대한 2 res)와 next함수를 갖습니다.

미들웨어는 계층이 계산을 수행하고 매개 변수를 보강 한 다음을 호출 할 것으로 예상합니다 next.

스택은 처리하지 않으면 아무것도하지 않습니다. Express는 들어오는 HTTP 요청이 서버에서 잡힐 때마다 스택을 처리합니다. 미들웨어를 사용하면 스택을 수동으로 처리합니다.

// express, you need to do nothing
// middleware
stack.handle(someData);

보다 완전한 예 :

var middleware = require("../src/middleware.js");

var stack = middleware(function(data, next) {
    data.foo = data.data*2;
    next();
}, function(data, next) {
    setTimeout(function() {
        data.async = true;
        next();
    }, 100)
}, function(data) {
    console.log(data);
});

stack.handle({
    "data": 42
})

명시 적으로 용어는 들어오는 모든 HTTP 요청에 대해 명시 적으로 처리하려는 작업 스택을 정의합니다.

연결이 아닌 Express (익스프레스) 측면에서 글로벌 미들웨어 및 라우팅 특정 미들웨어가 있습니다. 즉, 들어오는 모든 HTTP 요청에 미들웨어 스택을 첨부하거나 특정 경로와 상호 작용하는 HTTP 요청에만 미들웨어 스택을 첨부 할 수 있습니다.

익스프레스 및 미들웨어의 고급 예 :

// middleware 

var stack = middleware(function(req, res, next) {
    users.getAll(function(err, users) {
        if (err) next(err);
        req.users = users;
        next();
    });
}, function(req, res, next) {
    posts.getAll(function(err, posts) {
        if (err) next(err);
        req.posts = posts;
        next();
    })
}, function(req, res, next) {
    req.posts.forEach(function(post) {
        post.user = req.users[post.userId];
    });

    res.render("blog/posts", {
        "posts": req.posts
    });
});

var app = express.createServer();

app.get("/posts", function(req, res) {
   stack.handle(req, res);
});

// express

var app = express.createServer();

app.get("/posts", [
    function(req, res, next) {
        users.getAll(function(err, users) {
            if (err) next(err);
            req.users = users;
            next();
        });
    }, function(req, res, next) {
        posts.getAll(function(err, posts) {
            if (err) next(err);
            req.posts = posts;
            next();
        })
    }, function(req, res, next) {
        req.posts.forEach(function(post) {
            post.user = req.users[post.userId];
        });

        res.render("blog/posts", {
            "posts": req.posts
        });
    }
], function(req, res) {
   stack.handle(req, res);
});


답변

일을 단순화 한 후 웹 서버는 요청을 받아 응답을 출력하는 함수로 볼 수 있습니다. 따라서 웹 서버를 함수로 볼 경우 웹 서버를 여러 조각으로 구성하고 더 작은 기능으로 분리하여 구성이 원래 기능이 될 수 있습니다.

미들웨어는 다른 사람과 구성 할 수있는 더 작은 기능이며 재사용 할 수 있다는 것이 명백한 이점입니다.


답변

나는 이전 답변에서 언급되지 않은 것을 추가하기 위해 늦은 답변을 추가합니다.

이제 미들웨어가 클라이언트 요청서버 응답 사이에서 실행되고 있음을 분명히해야합니다 . 가장 일반적인 미들웨어 기능은 오류 관리, 데이터베이스 상호 작용, 정적 파일 또는 기타 리소스에서 정보 얻기입니다. 미들웨어 스택에서 이동하려면 다음 콜백을 호출해야합니다. 미들웨어 기능 끝에서 플로우의 다음 단계로 이동하는 것을 볼 수 있습니다.

app.use접근 방식을 사용하고 다음 과 같은 흐름을 가질 수 있습니다 .

var express = require('express'),
    app = express.createServer(),
    port = 1337;

function middleHandler(req, res, next) {
    console.log("execute middle ware");
    next();
}

app.use(function (req, res, next) {
    console.log("first middle ware");
    next();
});

app.use(function (req, res, next) {
    console.log("second middle ware");
    next();
});

app.get('/', middleHandler, function (req, res) {
    console.log("end middleware function");
    res.send("page render finished");
});

app.listen(port);
console.log('start server');

그러나 다른 접근 방식을 사용하고 각 미들웨어를 함수 인수로 전달할 수도 있습니다. 다음은 Midoware가 클라이언트로 다시 전송 되기 전에 midleware가 Twitter, Github 및 블로그 플로우를 가져 오는 MooTools Nodejs 웹 사이트예입니다response . 에서 함수가 인수로 전달되는 방식에 유의하십시오 app.get('/', githubEvents, twitter, getLatestBlog, function(req, res){. 사용 app.get은 GET 요청에 대해서만 app.use호출되며 모든 요청에 ​​대해 호출됩니다.

// github, twitter & blog feeds
var githubEvents = require('./middleware/githubEvents')({
    org: 'mootools'
});
var twitter = require('./middleware/twitter')();
var blogData = require('./blog/data');
function getLatestBlog(req, res, next){
    blogData.get(function(err, blog) {
        if (err) next(err);
        res.locals.lastBlogPost = blog.posts[0];
        next();
    });
}

// home
app.get('/', githubEvents, twitter, getLatestBlog, function(req, res){
    res.render('index', {
        title: 'MooTools',
        site: 'mootools',
        lastBlogPost: res.locals.lastBlogPost,
        tweetFeed: res.locals.twitter
    });
});


답변

expressjs 가이드 는 귀하의 질문에 대한 깔끔한 답변을 제공합니다. 가이드의 짧은 스 니펫을 게시하고 있으며 가이드는 매우 좋습니다.

Express 앱에서 사용할 미들웨어 작성

개요

미들웨어 함수는 요청 오브젝트 ( req ), 응답 오브젝트 ( res ) 및 애플리케이션의 요청-응답주기에서 다음 함수에액세스 할 수있는함수입니다. 다음 기능은 Express 라우터의 기능으로, 호출 될 때 현재 미들웨어에 이어 미들웨어를 실행합니다.

미들웨어 기능은 다음 작업을 수행 할 수 있습니다.

  • 모든 코드를 실행하십시오.
  • 요청 및 응답 오브젝트를 변경하십시오.
  • 요청-응답주기를 종료하십시오.
  • 스택에서 다음 미들웨어를 호출하십시오.

현재 미들웨어 함수가 요청-응답주기를 종료하지 않으면 next () 를 호출 하여 제어를 다음 미들웨어 함수로 전달 해야합니다 . 그렇지 않으면 요청이 중단됩니다.

여기에 이미지 설명을 입력하십시오

다음은 간단한 “Hello World”Express 응용 프로그램의 예입니다. 이 기사의 나머지 부분에서는 두 개의 미들웨어 함수를 정의하고 애플리케이션에 추가합니다. 하나 는 간단한 로그 메시지를 인쇄하는 myLogger 이고 다른 하나 는 HTTP 요청의 시간 소인을 표시하는 requestTime 1 입니다.

var express = require('express')
var app = express()

app.get('/', function (req, res) {
  res.send('Hello World!')
})

app.listen(3000)   

미들웨어 기능 myLogger

다음은“myLogger”라는 미들웨어 함수의 간단한 예입니다. 이 함수는 앱에 대한 요청이 통과 할 때 “LOGGED”를 인쇄합니다. 미들웨어 함수는 myLogger라는 변수에 지정됩니다.

var myLogger = function (req, res, next) {
  console.log('LOGGED')
  next()
}

next ()에 대한 호출을 주목하십시오 . 이 함수를 호출하면 앱에서 다음 미들웨어 함수가 호출됩니다. 다음 () 함수는 Node.js를 또는 익스프레스 API의 일부가 아니라 미들웨어 함수에 전달 된 세 번째 인수입니다. 다음 () 함수는 어떤 이름 할 수 있지만 관례 적으로 항상 “다음”이름이 지정됩니다. 혼동을 피하려면 항상이 규칙을 사용하십시오.

미들웨어 함수를로드하려면 미들웨어 함수를 지정하여 app.use ()를 호출 하십시오 . 예를 들어 다음 코드 는 루트 경로 (/) 로의 경로 이전에 myLogger 미들웨어 함수를 로드합니다 .

var express = require('express')
var app = express()

var myLogger = function (req, res, next) {
  console.log('LOGGED')
  next()
}

app.use(myLogger)

app.get('/', function (req, res) {
  res.send('Hello World!')
})

app.listen(3000)

앱이 요청을받을 때마다 “LOGGED”메시지를 터미널에 인쇄합니다.

미들웨어 로딩 순서는 중요합니다. 먼저로드 된 미들웨어 기능도 먼저 실행됩니다.

경우 myLogger이 루트 경로에 대한 경로 후로드, 요청이 결코 도달하지 루트 경로의 경로 핸들러가 요청 – 응답주기를 종료하기 때문에 응용 프로그램은, “LOGGED”를 인쇄하지 않습니다.

미들웨어 함수 myLogger는 단순히 메시지를 인쇄 한 후 next () 함수를 호출하여 요청을 스택의 다음 미들웨어 함수로 전달 합니다.


  1. 이 게시물에는 myLogger 미들웨어 만 포함됩니다. 추가 게시물을 보려면 여기 에서 원본 expressjs 안내서를 참조하십시오 .


답변

===== 매우 간단한 설명 =====

미들웨어는 종종 Express.js 프레임 워크에서 사용되며 node.js의 기본 개념입니다. 간단히 말해서, 기본적으로 응용 프로그램의 요청 및 응답 객체에 액세스 할 수있는 기능입니다. 내가 생각하고 싶은 방법은 요청이 응용 프로그램에 의해 처리되기 전에 요청이 통과하는 일련의 ‘확인 / 사전 화면’입니다. 예를 들어, 미들웨어는 애플리케이션으로 진행하기 전에 요청이 인증되는지 여부를 판별하고 요청이 인증되지 않은 경우 또는 각 요청을 로깅하기 위해 로그인 페이지를 리턴하는 데 적합합니다. 다양한 기능을 가능하게하는 많은 타사 미들웨어를 사용할 수 있습니다.

간단한 미들웨어 예 :

var app = express();
app.use(function(req,res,next)){
    console.log("Request URL - "req.url);
    next();
}

위의 코드는 들어오는 각 요청에 대해 실행되고 요청 URL을 기록합니다. next () 메소드는 본질적으로 프로그램을 계속할 수있게합니다. next () 함수가 호출되지 않으면 프로그램은 더 이상 진행되지 않으며 미들웨어 실행시 정지됩니다.

몇 가지 미들웨어 문제 :

  1. 요청이 각 순서대로 순차적으로 진행되므로 애플리케이션의 미들웨어 순서가 중요합니다.
  2. 미들웨어 함수에서 next () 메소드를 호출하지 않으면 요청 처리가 중단 될 수 있습니다.
  3. 미들웨어 기능에서 req 및 res 오브젝트를 변경하면 req 및 res를 사용하는 애플리케이션의 다른 부분에서 변경 사항을 사용할 수 있습니다.

답변

미들웨어는 입력 / 소스 다음에 중간에서 실행되는 기능으로, 최종 출력 일 수 있거나주기가 완료 될 때까지 다음 미들웨어가 사용할 수있는 출력을 생성합니다.

마치 완성, 평가 또는 거부 될 때까지 움직일 때 수정되는 조립 라인을 통과하는 제품과 같습니다.

미들웨어는 일부 값 (예 : 매개 변수 값)이 작동 할 것으로 예상하고 일부 논리에 따라 미들웨어가 다음 미들웨어를 호출하거나 호출하지 않거나 클라이언트에 응답을 보냅니다.

미들웨어 개념을 여전히 파악할 수없는 경우 데코레이터 또는 명령 패턴 체인과 유사한 방식입니다.


답변

미들웨어는 사용자 정의 핸들러가 호출되기 전에 Express js 라우팅 계층에서 호출하는 체인 함수의 서브 세트입니다. 미들웨어 기능은 요청 및 응답 오브젝트에 대한 전체 액세스 권한을 가지며 이들 중 하나를 수정할 수 있습니다.

미들웨어 체인은 항상 정의 된 순서대로 호출되므로 특정 미들웨어가 수행하는 작업을 정확히 아는 것이 중요합니다.
미들웨어 함수가 완료되면 다음 인수를 함수로 호출하여 체인에서 다음 함수를 호출합니다.
전체 체인이 실행 된 후 사용자 요청 핸들러가 호출됩니다.