TIL 17

모모·2021년 11월 27일
0

TIL

목록 보기
17/28

미들웨어

(공식문서를 옮겨적으며 개념을 정리했습니다.
https://expressjs.com/en/guide/writing-middleware.html)

미들웨어 함수는 요청 오브젝트(req), 응답 오브젝트(res), 그리고 next 함수(애플리케이션의 요청-응답 사이클에서)에 대한 접근 권한을 갖는다.

미들웨어 함수가 하는 일

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

현재 미들웨어 함수가 req-res 사이클을 끝내지 않으면, next()를 호출해 한다. 이는 다음 미들웨어 함수로 컨트롤을 넘겨주기 위함이다. 그렇지 않으면 request가 정지된다.

Express5부터 Promise를 리턴하는 미들웨어 함수는 reject나 error 발생시 next(value)를 호출한다.
즉, next는 rejected value나 에러 메시지 중 하나로 호출된다.

Middleware function 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)

미들웨어 함수를 사용하려면 app.use(미들웨어)로 호출해야 한다.
미들웨어의 로드 순서는 중요하다. 먼저 로드되는 미들웨어 함수가 먼저 실행되기 때문이다.
myLogger가 root path('/')뒤에 실행되면, request가 절대 myLogger에 접근하지 못하여 LOGGED를 출력하지 못한다. root path의 route handler(function(req, res)) 가 req-res 사이클을 종료시키기 때문이다.

Middleware function requestTime

다음 미들웨어 함수 'requestTime'을 작성하고, request 오브젝트에 requestTime 프로퍼티를 추가하자.

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

var requestTime = function (req, res, next) {
  req.requestTime = Date.now()
  next()
}

app.use(requestTime)

app.get('/', function (req, res) {
  var responseText = 'Hello World!<br>'
  responseText += '<small>Requested at: ' + req.requestTime + '</small>'
  res.send(responseText)
})

app.listen(3000)

이제 앱은 requestTime 미드웨어 함수를 사용한다.
또한, root path 경로의 콜백 함수는 미들웨어 함수가 request 객체에 추가한 프로퍼티를 사용한다.(get root path 경로 함수 바디에 req.requestTime이 사용되는 것을 확인)

Middleware function validateCookies

새로운 쿠키를 validate하고, 쿠키가 유효하지 않다면 400 response를 보내는 미들웨어 함수를 만들자.
여기 외부 async 서비스로 쿠키를 승인하는 cookieValidator 함수가 있다.

async function cookieValidator (cookies) {
  try {
    await externallyValidateCookie(cookies.testCookie)
  } catch {
    throw new Error('Invalid cookies')
  }
}

여기에서 cookie-parser 미들웨어를 사용하여 req 오브젝트에서 들어오는 쿠키를 파싱하고 cookieValidater 함수에 전달한다.
validateCookies 미들웨어는 rejection시, 자동으로 에러 핸들러를 작동하는 Promise를 리턴한다.

var express = require('express')
var cookieParser = require('cookie-parser')
var cookieValidator = require('./cookieValidator')

var app = express()

async function validateCookies (req, res, next) {
  await cookieValidator(req.cookies)
  next()
}

app.use(cookieParser())

app.use(validateCookies)

// error handler
app.use(function (err, req, res, next) {
  res.status(400).send(err.message)
})

app.listen(3000)

stack과 전체 Node.js API에 있는 request 객체, response 객체, next 미들웨어 함수에 접근할 수 있기 때문에 미들웨어 함수를 활용할 수 있는 가능성은 무궁무진하다.

body-parser

파싱이란 프로그램을 분석하여, 실행 환경에서 동작할 수 있도록 내부 포맷으로 변환하는 것이다.

클라이언트에서 API POST 및 PUT 요청 시, 서버는 이 요청의 payloads(body)를 바로 사용할 수 없다. 서버에서 해석 가능한 형태로 변환하는 과정을 거쳐야 하는데, Node.js의 미들웨어인 body-parse가 요청받은 body값을 파싱한다.

Express 버전 4.16.0부터 body-parser가 built-in 미들웨어로 추가되었다. 즉, 따로 import 하지 않고, 미들웨어 함수 사용법에 따라 다음과 같이 코드를 작성하여 body-parser를 사용할 수 있다.

app.use(express.json([option])) // incoming request payloads를 JSON으로 parse
app.use(express.text([option])) // incoming request payloads를 문자열로 parse

// 또는 아래와 같이 사용할수도 있다.
const jsonParser = express.json()
app.use(jsonParser)

option에 관한 자세한 설명은 공식문서에서 확인하자
(https://expressjs.com/en/resources/middleware/body-parser.html)

0개의 댓글