kakasoo

Express 프레임워크 만들기(1) 본문

프로그래밍/JavaScript

Express 프레임워크 만들기(1)

카카수(kakasoo) 2021. 5. 20. 10:28
반응형

나는 express를 알고 있을까?

const http = require("http");
const app = require("./app.js");

const server = http.createServer(app);
server.listen(PORT, () => console.log("Server is opened."));

일반적으로 node.js와 Express.js를 사용해 서버를 만든다면 위의 코드는 공통으로 들어갈 것입니다. 그렇기 때문에 위 코드를 이해하는 데에는 큰 어려움이 없을 것 같습니다. 그런데 공부를 하면서 헷갈리는 부분이 참 많았죠. 하지만 당장 서버를 만드는 데에 필요한 것 같지는 않아 방치하다 이제야 그 고민을 마주합니다.

 

  1. Framework는 뭐지?
  2. Server와 Express의 차이는 뭐지?
  3. ( 나아가서 ) 애초에 나는 이 둘을 "제대로" 다루고 있는 건 맞나?
  4. ( 나아가서 ) 애초에 나는 이 둘을 "알고" 다루고 있는 것은 맞나?

이런 질문들의 답은 항상 글귀를 읽기보다도 직접 코드를 작성함에서 얻곤 했습니다. 그러면 이 질문들에 답하기 위해서라도, 다시 코드를 보도록 할까요?

 

const http = require("http");
const express = require("express");

const app = express(); // 사실 app은 express를 이용해 만든 것이었습니다.
const PORT = 3000;
const server = http.createServer(app);

server.listen(PORT, () => console.log("Server is opened."));

핵심이 되는 부분은 여기서 app 입니다. 이 app이 express를 사용해 만든 application이기 때문입니다. 그러니까, 앞서 고민거리였던 서버와 프레임워크에 대한 구분은 이렇게 설명할 수 있을 것 같습니다.

 

"app은 express 범주이고, 그 app을 http에 올리면 Server인 거야."

또는

"Server를 만들 때 실질적인 동작에 관한 부분이 app에 해당해."

 

( + 서버와 프레임워크 모두 Node.js라는 언어로 작성되고 있고요. )

 

제가 이해한 것을 비유로 설명드리자면, 저는 서버와 어플리케이션의 관계를 레코드판에 비유하곤 합니다.

( 저도 레코드를 써본 적은 없습니다만 )

우리가 축음기로 음악을 듣기 위해서는 레코드가 필요합니다. 즉, 음악을 듣기 위해서는 레코드판이 필요한 것이지만, 어떤 음악인지는 결국 레코드에 달린 문제입니다. 여기서 축음기를 Server, 레코드를 Application에 비유하면 적절할 거 같습니다.

 

"그러면 Express는 음악을 만들기 쉽게 도와주는 툴이라고 생각하면 되겠군요."

 

네. 저는 그렇게 생각하고 있습니다. 그러면 얼추 1번과 2번의 질문에 나름 답변이 된 거 같습니다. 그러면 나머지 3번과 4번을 풀기 위해서는 어떻게 해야 할까요?

 

운이 좋게도 3번에 대한 정답은 Express 공식 문서를 통해 해결할 수 있을 것이고, 4번에 대한 문제는 조금 복잡하긴 하지만 github에서 Express 코드를 직접 해석해보면서 해결할 수 있을 것입니다. 하지만 이는 시간을 상당히 잡아먹는 데다가, 사실 내부 구조를 모른다고 한들 Express로 웹을 만드는 게 불가능한 것도 아니기 때문에 굳이 도전해보고 싶은 마음이 크게 들지 않을 거 같습니다.

 

그래서 제가 대신 하고자 합니다! 여러분들을 위해 github Express.js의 코드를 읽고, 해석해서, ES6에 익숙한 여러분들이, 이해할 수 있도록 도울 생각입니다!

( 우레와 같은 박수! )

 

여러분들이 Express를 다뤄본 적 있는, 다뤄본 JavaScript 개발자라면, 이 글을 읽는 게 결코 시간 낭비는 아닐 것입니다.

 

어려운 건 너굴맨이 해치웠다구!

Express 없이 서버 만들기

Express에 대해서 이해하는 가장 좋은 방법은, 사실 Express를 써보지 않는 것일지도 모릅니다. 그래서 일단 Express 없이, Express와 똑같이 동작하는 서버를 만들어보고자 합니다.

아래는 간단하게 "HELLO WORLD"를 보여주는 코드입니다.

// Express를 사용한 코드
const http = require("http");
const express = require("express");

const app = express(); // 사실 app은 express를 이용해 만든 것이었습니다.

app.get("/", (req, res, next) => {
    res.send("HELLO WORLD!");
});

const PORT = 3000;
const server = http.createServer(app);

server.listen(PORT, () => console.log("Server is opened."));
// node.js 공식 홈페이지 About page에 나와 있는 코드
const http = require("http");

const PORT = 3000;
const server = http.createServer((req, res) => {
    res.setHeader("Content-Type", "text/plain");
    res.end("HELLO WORLD!");
});

server.listen(PORT, () => console.log("Server is opened."));

 

app을 지웠으니, 당연히 그 부분에 대한 코드를 작성해주어야 합니다. app을 대체함으로써 우리가 작성해준 내용을 보면, 결국 아래처럼 생각해볼 수 있을 거 같습니다.

  1. app은 콜백 함수이다.
  2. URL 경로에 따라서 라우팅 해주는 기능이 필요하다.
  3. ( 위에는 get만 나와 있지만 ) method에 대해서도 라우팅 해주는 기능이 필요하다.
  4. Header들을 추가해주어야 한다.

( 물론 이 외에도 해야 할 게 아주 많습니다. 가령 res.send()는 원래 response에는 없는 method입니다.이 역시 express가 response를 확장해 만든 method이기 때문입니다. )

 

그러면 어떤 함수 ( ex. express )를 실행한 결과에 의해 app이 만들어진다고 가정하고 작성해봅시다. app 자체가 콜백 함수였으니, 그렇다면 그 함수는 함수를 return 하는 종류의 함수일 것입니다.

 

const http = require("http");
const PORT = 3000;

// 이 부분은 분리해서 모듈이나 라이브러리로 만든다고 가정합니다.
const TExpress = () => (req, res) => {
    res.setHeader("Content-Type", "text/plain");
    res.end("HELLO WORLD!");
};

const app = TExpress();
const server = http.createServer(app);

server.listen(PORT, () => console.log("Server is opened."));
const TExpress = () => (req, res) => {
    res.setHeader("Content-Type", "text/plain");
    res.end("HELLO WORLD!");
};

 

어떤 application (요청에 대한 처리를 담고 있는 콜백 함수) 을 생성하여 http.createServer()에 전달하기만 하면 되는 것이니, http와 그 관련 코드들은 변하지 않을 것입니다. 따라서 TExpress라는 부분만 잘 작성해두면 될 거 같습니다.

하지만 이런 방식으로 작성한다면, 각 URL 단위, 메서드 단위로 코드를 분리해낼 수 없을 거 같습니다. 일단 분리를 하고 나서 생각하는 게 좋을 거 같습니다.

반응형