Day 7 : 왜 굳이 웹 서버 프레임워크를 사용해야 하나?

2023. 5. 25. 15:21International Sign Lang 프로젝트/백엔드

728x90

2023.05.24 - [Project ISL/프론트엔드] - Day 6 : 첫걸음은 '레이아웃 설계'로부터

 

Day 6 : 첫걸음은 '레이아웃 설계'로부터

2023.05.18 - [Project ISL/프론트엔드] - Day 5 : 세계지도 인터랙션, 국가별 호버 이벤트와 법규(?) Day 5 : 세계지도 인터랙션, 국가별 호버 이벤트와 법규(?) 2023.05.17 - [Project ISL/프론트엔드] - Day 4 : 노력

xpmxf4.tistory.com

2023.05.14 - [Project ISL/기획] - Day1 : "일단 시작" 이 아니라 "설계부터"

 

Day1 : "일단 시작" 이 아니라 "설계부터"

예전 개발을 막 시작했을 시절에는 일단 코드부터 작성하고 봤는 데 이제는 코드부터 들입다 작성하는 게 오히려 미래에 프로젝트 진행을 더 더디게 만든다는 걸 알아 기능 리스트업부터 해요.

xpmxf4.tistory.com

이전 글들을 보고 와주시면 감사하겠습니다!


이제 어느 정도의 레이아웃은 완성이 되었고,

슬슬 프론트에 백엔드 API를 붙일 만한 시간이 왔습니다.

 

그래서 Day 1 의 초기 기획처럼 node로 백엔드를 구축하려고 하다 보니

다음과 같은 의문이 들더라구요?

백엔드 칸반 보드

어차피 API라고 해봤자 하나의 테이블에 대해서

5개 정도밖에 나오지 않는 다면, 굳이 Node.js + Express을 같이

사용해야 할 필요가 있을까?

 

다 서버리스를 통해 람다로 배포할꺼라면, 서버를 최대한 경량화해

올리는 게 이득이 아닐까?

 

그래서 순수한 JavaScript, 즉 Node.js 만으로 API 코드를 하나 예시로 작성해 봤다.

const http = require('http');

const server = http.createServer((req, res) => {
    if(req.url === "/api/example" && req.method === "GET") {
        res.writeHead(200, {'Content-Type': 'application/json'});
        res.end(JSON.stringify({message: 'Hello World'}));
    }
    else {
        res.writeHead(404);
        res.end();
    }
});

server.listen(3000, () => {
    console.log('Server is running on port 3000...');
});

성공적으로 /api/example 에 통신 완!

이렇게만 해도 처리할 수 있다면

굳이 웹 프레임워크를 사용할 필요가 있나?라는 생각이 들지만

사람들이 이렇게 하지 않는 이유에는 분명 이유가 있을 것이라고 생각해

찾아봤습니다!

 

MDN 은 과학

Server-side web frameworks - Web 개발 학습하기 | MDN

 

Server-side web frameworks - Web 개발 학습하기 | MDN

This article has shown that web frameworks can make it easier to develop and maintain server-side code. It has also provided a high level overview of a few popular frameworks, and discussed criteria for choosing a web application framework. You should now

developer.mozilla.org

해당 사이트에서 나의 의문에 대한 답을 얻을 수 있었습니다.

 

ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

페이지 초입부터 대문짝만 한 게 무조건

웹 프레임워크를 사용하라고 하는 거 아니냐고요,,,

 

마음의 상처와 함께 그렇다면 도대체 왜!

우리가 웹 프레임워크를 사용해야 하는지 알아보겠습니다!

 

1. HTTP 요청 및 응답으로 직접 작업

우리가 마지막 기사에서 봤듯이 웹 서버와 브라우저는 HTTP protocol을 통해 통신합니다 —
서버는 브라우저에서 오는 HTTP요청을 기다리고, HTTP응답에 정보를 반환합니다.

웹 프레임워크는 이러한 요청과 응답을 할 서버 측 코드를 만드는데 작성할 문법을 단순화합니다.
이것은 당신의 일과 상호작용을 쉽게 하고, 저수준 네트워킹 프리미티브보다 높은 수준의 코드를 이용한다는 것을 의미합니다.

즉 통신 코드의 문법을 단순화하고,

저수준의 네트워킹 코드를 사용하지 않아도 된다는 말입니다!

 

아니 문법만 단순해지는 거면, 사실 필요 없지 않나?

라고 생각할 수 있습니다.

 

하지만 제가 여러 포스팅에서 얘기했다시피,

기술들이 항상 장점이 있다면 동시에 단점도 존재하기 마련입니다.

 

저수준의 네트워킹 코드를 사용한다는 것은

동시에 우리가 네트워크 통신을 하면서 일일이 신경써야 하는 경우의 수들이

정말 많다는 것을 의미합니다.

 

하지만 웹 프레임워크를 사용한다면 이것을 일일히 구현하거나

신경을 쓸 필요가 없어진다는 얘기이죠!

 

req.get =
req.header = function header(name) {
  if (!name) {
    throw new TypeError('name argument is required to req.get');
  }

  if (typeof name !== 'string') {
    throw new TypeError('name must be a string to req.get');
  }

  var lc = name.toLowerCase();

  switch (lc) {
    case 'referer':
    case 'referrer':
      return this.headers.referrer
        || this.headers.referer;
    default:
      return this.headers[lc];
  }
};

위 코드는 express의 request.js라는

request를 담당하는 파일의 일부입니다.

코드 양이 이 정도라면, 사실 개인이 알아서 다 구현하고도 남죠.

 

하지만 이렇게 생긴 코드가

lib/request.js

521 줄이나 존재하죠...

즉 request 를 안전하게 사용자가 처리하기 위해

이 정도의 코드가 필요하다는 것을 우리는 알 수 있습니다.

 

2. 요청을 적절한 처리자에게 라우팅

대부분의 사이트는 여러 개의 다른 리소스를 특정된 URL을 통해 접근할 수 있도록 제공합니다.
통합된 함수로 모든 것을 처리하는 건 유지하기가 매우 힘듭니다.

그래서 웹 프레임워크는 특별한 처리 함수로 URL패턴을 매핑하는 기능을 제공합니다.
이러한 접근 방법은 유지 보수 기간에 이점이 있습니다. 왜냐하면 기본 코드를 변경하지 않고도 특정 기능을 제공하는 데 사용되는 URL을 변경할 수 있기 때문입니다.

위에서 일일이 구현했던 Node.js의 코드를 보게 되면

const server = http.createServer((req, res) => {
    if(req.url === "/api/example" && req.method === "GET") {
        res.writeHead(200, {'Content-Type': 'application/json'});
        res.end(JSON.stringify({message: 'Hello World'}));
    }
    else if(req.url === "/api/example2" && req.method === "GET") {
    	// something else
    }
    else {
        res.writeHead(404);
        res.end();
    }
});

리소스를 URL에 매핑시키는 함수는 정말 길기도 하지만

또 하나의 특징은 하나의 함수에서 일일이 if로 URL을

가려내야 하는 형태를 띠고 있습니다. 

 

express를 사용한다면 위의 코드는 다음과 같이 변형할 수 있습니다.

const express = require('express');

const app = express();

app.get('/api/example', (req, res) => {
  res.send('Hello, world!');
});

app.get('/api/example2', (req, res) => {
	// something else
});

app.listen(3000, () => {
  console.log('App listening on port 3000!');
});

훨씬 가독성도 좋고, 보기에도 깔끔한 걸 확인할 수 있습니다!

 

 

3. Request의 데이터에 쉽게 액세스 할 수 있도록 지원

데이터는 다양한 방법으로 HTTP응답에 인코딩 될 수 있습니다.

서버에서 파일이나 데이터를 얻기 위한 HTTP GET 요청은
URL인자나 URL구조를 요구한 데이터를 인코딩할 수 있습니다.

서버에 있는 리소스를 업데이트를 요청하는 HTTP POST는 요청 본문에
"POST data"로 업데이트 정보를 대신 포함합니다.
또한 HTTP 요청은 클라이언트 측 쿠키에서 현재 세션 또는 사용자에 관한 정보를 포함할 수 있습니다.

이 설명이 잘 이해가 안 간다고요?

그러셔도 충분히 괜찮습니다!

 

이번에도 코드의 예시로 한번 볼까요?

const http = require('http');

const server = http.createServer((req, res) => {
  const name = req.query.name;
  const age = req.query.age;

  res.end(`Hello, ${name}! You are ${age} years old.`);
});

server.listen(3000, () => {
  console.log('App listening on port 3000!');
});

위 코드는 아까와 비슷하게 순수한 JavaScript로 구현한 서버입니다.

이번에는 날아온 req 안에 담긴 name, age 속성을 res 안에 담아서 보내는 코드입니다.

위를 express로 한번 구현해 볼까요?

const express = require('express');

const app = express();

app.get('/', (req, res) => {
  const name = req.query.name;
  const age = req.query.age;

  res.send(`Hello, ${name}! You are ${age} years old.`);
});

app.listen(3000, () => {
  console.log('App listening on port 3000!');
});

뭐가 다르죠?

별로 달라 보이는 게 없다고요?

정말로? 혼또니?

.

.

.

.

.

정답입니다!

 

사실 저렇게만 보면 차이를 알 수 없습니다.

하지만 공식문서를 가보면 그 차이를 알 수 있습니다.

https://nodejs.org/api/http.html#class-httpclientrequest

 

HTTP | Node.js v20.2.0 Documentation

HTTP# Source Code: lib/http.js To use the HTTP server and client one must require('node:http'). The HTTP interfaces in Node.js are designed to support many features of the protocol which have been traditionally difficult to use. In particular, large, possi

nodejs.org

https://expressjs.com/en/api.html#req

 

Express 4.x - API Reference

Express 4.x API express() Creates an Express application. The express() function is a top-level function exported by the express module. var express = require('express') var app = express() Methods express.json([options]) This middleware is available in Ex

expressjs.com

두 공식문서에 워낙 req에 대한 내용이 많아서

이번에는 직접 긁어오지는 못하지만!

express의 req 관련 속성과 메서드들은 좀 더 고수준으로 만들어

사용자가 더 쉽게 속성에 접근할 수 있도록 만들었다는 것을 확인하실 수 있습니다!

 

4. 데이터베이스 액세스 추상화 및 간소화

웹 사이트는 사용자와 사용자에 대한 정보 공유를 위한 데이터를 저장하기 위해서 데이터베이스를 사용합니다.
웹 프레임 워크는 종종 데이터베이스 읽기, 쓰기, 쿼리, 삭제 조작을 추상화할 수 있는 데이터베이스 계층을 제공합니다.
이러한 추상 계층을 객체 관계형 매퍼(ORM)라고 합니다.

즉, ORM을 사용할 수 있다는 것입니다.

아마 RDB에 공부를 많이 하신 분들이라면

ORM을 사용할 수 있다는 게 얼마나 편해지는 것인지 아실 겁니다!

(아직 모르신다면 많이 편해지는 것이라고 일단은 넘기시면 됩니다!)

 

하지만 아까도 그랬듯 장점이 있으면 동시에 단점도 있는 법!

ORM이라고 무조건 좋지는 않습니다!

어쨌든 ORM이라는 추상 계층을 웹 프레임워크가 제공해 준다!

라고 알고 넘어가며, Java에서 쓰이는 ORM 인 JPA 왕 김영한 님의 쇼츠 보고 넘어가실게요!

 

https://www.youtube.com/shorts/CbTG9TCNAXw

ORM 은 안 중요하다는 갓의 말씀!

마무리하며

쓰다 보니 글이 많이 길어졌습니다!

오늘은 왜 굳이 웹 프레임워크를 사용해야 하나에 대한 글이었습니다!

추가적인 설명이 보고 싶으시다면 위에 올려둔 MDN 사이트를 직접 보시는 걸 추천합니다!

 

언제나 피드백은 환영입니다 여러분!

https://github.com/xpmxf4/ISL_FrontEnd

 

GitHub - xpmxf4/ISL_FrontEnd

Contribute to xpmxf4/ISL_FrontEnd development by creating an account on GitHub.

github.com

https://github.com/xpmxf4/ISL_BackEnd

 

GitHub - xpmxf4/ISL_BackEnd

Contribute to xpmxf4/ISL_BackEnd development by creating an account on GitHub.

github.com

그리고 스타... 부탁드립니다 ㅎㅎㅎ

728x90