'express middleware'에 해당되는 글 1건

지금 껏 나는 express의 본질인 connect middleware에 대해서 정확하게 이해하지 못하고 node.js를 사용해 온 것 같다.

미들웨어를 잘 설명하는 답변을 찾아 포스팅한다.

In most frameworks you get a request and you want to return a response. Because of the async nature of Node.js you run into problems with nested call backs if you are doing non trivial stuff. To keep this from happening Connect.js (Express.js is a layer on top of connect) has something that is called middleware which is a function with 2, 3 or 4 parameters.

대부분의 프레임워크에서는 request와 response가 있다. node.js의 비동기적인 특성 때문에 nested callback 문제에 부딪힐 수 있다(정확히 무슨말인지 이해가 안감)..

이를 위해서 Express는 미들웨어를 제공한다..

function (<err>, req, res, next) {}

Your Express.js app is a stack of these functions.

enter image description here

위의 그림이 명쾌하게 설명해주고 있다. request가 들어오면 built-in middleware가 실행되고(express는 네가지 미들웨어를 가진다. 

 

그 다음 router middleware가 실행된다. 이 시점에서 stack 에 있는 여러 routing function을 실행할 수 있다.  이렇게 한 스택에 있는 function을 사용하기 위해서 사용되는 메소드가 next()이다. 

The router is special, it's middleware that lets you execute one or more middleware for a certain url. So it's a stack inside a stack.

router는 특별하다. 그 것은 특정한 url에 들어온 요청을 한개이상의  middleware를 써서 실행하게 도와준다.  그렇기 때문에 stack안의 stack구조를 갖게된다.

So what does next do? Simple, it tells your app to run the next middleware. But what happens when you pass something to next? Express will abort the current stack and will run all the middleware that has 4 parameters.

그렇다면 next가 하는 역할은 무엇일까? 

expressjs 공식홈에 자세한 설명이 나와있다.


Middleware is a function with access to the request object (req), the response object (res), and the next middleware in line in the request-response cycle of an Express application, commonly denoted by a variable named next. Middleware can:

  • Execute any code.
  • Make changes to the request and the response objects.
  • End the request-response cycle.
  • Call the next middleware in the stack.

If the current middleware does not end the request-response cycle, it must call next() to pass control to the next middleware, otherwise the request will be left hanging.

하나의 미들웨어는 request object 와 response object에 접근하는 function이다. req-res 사이클에서 next 미들웨어에도 접근할 수 있다. 이렇게 한 스택안에 여러가지의 routing middleware가 있을 때 next middleware에 접근할 수 있는 function이 next()이다... 

그렇다면 응용 예를 하나 보겠다.

app.param() 메소드를 통한 응용인데 ...

app.param()은 공식홈에서 이렇게 가이드를 하고 있다.

Add callback triggers to route paramters, where name is the name of the parameter or an array of them, and function is the callback function. The parameters of the callback function are the request object, the response object, the next middleware, and the value of the parameter, in that order.

For example, when :user is present in a route path, you may map user loadig logic to automatically provide req.user to the route, or perform validations on the parameter input.

첫번째 인자에 parameter를 주는데 이 파라미터가 next를 통해 다음 미들웨어를 호출할때 index로 쓰인다. 무슨 말인고 하면, 아래와 같이 app.param('user' 라고 user 파라미터를 주었다면 next를 통해 다음 라우팅 미들웨어를 실행할 때 user파라미터를 가지는 middleware가 실행되는 것이다.

app.param('user', function(req, res, next, id) {

  // try to get the user details from the User model and attach it to the request object
  User.find(id, function(err, user) {
    if (err) {
      next(err);
    } else if (user) {
      req.user = user;
      next();
    } else {
      next(new Error('failed to load user'));
    }
  });
});


따라서 아래와 같이 응용을 할 수 있게 되는데,  param을 통해 load 미들웨어를 실행하고 id를 파라미터로 가지는 미들웨어를 next()를 통해 선택적으로 실행한다. 즉 id 파라미터를 가지는 url로 들어오는 모든 요청은 aritcles.load 미들웨어를 거쳐 실행된다. 


app.param('id', articles.load); app.get('/articles', articles.index); app.get('/articles/new', auth.requiresLogin, articles.new); app.post('/articles', auth.requiresLogin, articles.create); app.get('/articles/:id', articles.show); app.get('/articles/:id/edit', articleAuth, articles.edit); app.put('/articles/:id', articleAuth, articles.update); app.delete('/articles/:id', articleAuth, articles.destroy);






블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

댓글을 달아 주세요