[Node.js/Koa] Koa 미들웨어

익스프레스를 다루며, 미들웨어(Middleware)에 대한 것을 알아봤습니다. 미들웨어는 요청과 응답 중간에서 동작하는 것들을 미들웨어라고 부릅니다. 라우터 등이 대표적이 미들웨어의 일종입니다. Koa 라이브러리도 미들웨어를 중요하게 다룹니다.

Koa 미들웨어

Koa는 미들웨어 함수를 등록하기 위해 use() 함수를 사용합니다. 이 use() 함수의 기본형은 다음과 같습니다.

use(미들웨어 함수);

미들웨어 함수는 미들웨어를 기술하는 함수로, 다음과 같은 구조를 갖습니다.

(context, next) => {};

첫 번째 인자인 context는 요청/응답에 대한 정보를 가지고 있습니다. 두 번째 인자인 next는 다음 미들웨어를 호출하는 함수입니다. 만약 next함수가 없다면 다음에 오는 미들웨어를 처리하지 않습니다.

그럼, 미들웨어 작성법을 알아봤으니 지난번에 만들어둔 코드에 미들웨어 기능을 더해보겠습니다.

const koa = require('koa');

const app = new koa();
const PORT = process.env.PORT || 3000;

app.use((context, next) => {
    console.log(context.url);
    console.log('1st Middleware');

    next();
});

app.use((context, next) => {
    console.log('2nd Middleware');

    next();
});

app.use(context => {
    context.body = 'Hello Koa!';
});

app.listen(PORT, () => {
    console.log(`Koa is listening to port number: ${PORT}`);
});

node 파일경로명령으로 서버를 실행하고, localhost:3000에 접속하면 터미널에 다음과 같은 로그가 찍힙니다.중간에 /favicon.ico는 사이트의 아이콘 파일인데, 기본적으로 요청하는 파일이라 콘솔에 나타난 것 입니다. 없는 경우도 있을 수 있으니 크게 신경쓰지 마세요.
아무튼, 결과적으로 우리가 미들웨어로 작성해줬던 내용들이 터미널에 잘 나타났죠?

이번에는 방금 작성한 코드에서 첫 번째 미들웨어의 next() 함수를 주석처리 해보겠습니다.

const koa = require('koa');

const app = new koa();
const PORT = process.env.PORT || 3000;

app.use((context, next) => {
    console.log(context.url);
    console.log('1st Middleware');

    //next(); 주석 처리
});

app.use((context, next) => {
    console.log('2nd Middleware');

    next();
});

app.use(context => {
    context.body = 'Hello Koa!';
});

app.listen(PORT, () => {
    console.log(`Koa is listening to port number: ${PORT}`);
});

미들웨어를 연결해주는 next가 사라졌으므로, 첫 번째 등록된 미들웨어만 실행되었습니다.

next() 함수는 Promise를 반환한다

사실 use() 함수의 next()는 익스프레스에서도 존재했었는데요. Koanext()Pormise를 반환합니다. 익스프레스와는 구분되는 특징인데요. 프로미스를 반환하기때문에 연결된 다음 미들웨어의 next()가 반환하는 프로미스는 이전 미들웨어가 종료되어야 반환됩니다.

next()는 프로미스를 반환하므로 다음과같이 then()을 사용할 수 있습니다.

const koa = require('koa');

const app = new koa();
const PORT = process.env.PORT || 3000;

app.use((context, next) => {
    console.log(context.url);
    console.log('1st Middleware');

    next().then(() => {
        console.log('End');
    });
});

app.use((context, next) => {
    console.log('2nd Middleware');

    next();
});

app.use(context => {
    context.body = 'Hello Koa!';
});

app.listen(PORT, () => {
    console.log(`Koa is listening to port number: ${PORT}`);
});

또한 Koa에서는 async/await 문법을 정식 지원하기 때문에 익스프레스처럼 try~catch를 통한 예외처리나, 추가 라이브러리 설치를 할 필요도 없습니다.

const koa = require('koa');

const app = new koa();
const PORT = process.env.PORT || 3000;

app.use(async (context, next) => {
    console.log(context.url);
    console.log('1st Middleware');

    await next();
    console.log('End with async/await');
});

app.use((context, next) => {
    console.log('2nd Middleware');

    next();
});

app.use(context => {
    context.body = 'Hello Koa!';
});

app.listen(PORT, () => {
    console.log(`Koa is listening to port number: ${PORT}`);
});

좋은 웹페이지 즐겨찾기