Node.js - Express

본 글은 네이버 부스트캠프를 위해 학습한 내용을 노션에서 이전한 게시글입니다.


1. Express란

  • Node.js를 위한 빠르고 개방적인 간결한 웹 프레임워크
  • Node.js를 사용하여 서버를 개발하고자 하는 개발자들을 위하여 서버를 쉽게 구성할 수 있게 만든 프레임워크
    • 프레임워크란 : 클래스와 라이브러리의 집합체

2. Express 특징

  • http 모듈의 요청과 응답 객체에 추가 기능들을 부여하였음
  • 라우터로 코드를 분리하기 쉬워 유지보수 또한 용이함

3. Express와 비슷한 웹 서버 프레임워크

  • koa
  • hapi

4. Express 기능

4.1. Route

  • URI(또는 경로) 및 특정한 HTTP 요청 메소드(GET, POST 등)인 특정 엔드포인트에 대한 클라이언트 요청에 애플리케이션이 응답하는 방법을 결정하는 것
    • ENDPOINT API가 서버에서 리소스에 접근할 수 있도록 가능하게 하는 URL
  • 각 라우트는 하나 이상의 핸들러 함수를 가질 수 있으며, 이러한 함수는 라우트가 일치될 때 실행됨
  • Source Code
  • Reference

4.1.1. 파라미터 전달

  • URI 뒤에 ‘:parameter’ 를 통해 파라미터를 주고 받을 수 있음
    • 여러 개의 파라미터도 사용할 수 있음
  • Source Code

4.1.2. Redirect

  • response.redirect 메서드를 통해 redirect 기능을 지원함
  • Source Code

4.2. Middleware

4.2.1. Middleware란

  • 양 쪽을 연결하여 데이터를 주고받을 수 있도록 중간에서 매개 역할을 하는 소프트웨어
  • 네트워크를 통해서 연결된 여러 개의 컴퓨터에 있는 많은 프로세스들에게 어떤 서비스를 주고 받을 수 있도록 연결해주는 소프트웨어 Untitled 미들웨어 함수가 적용되는 HTTP 메소드. 미들웨어 함수가 적용되는 경로(라우트). 미들웨어 함수. ### 미들웨어 함수에 대한 콜백 인수(일반적으로 “next”라 불림). 미들웨어 함수에 대한 HTTP 응답 인수(일반적으로 “res”라 불림). 미들웨어 함수에 대한 HTTP 요청 인수(일반적으로 “req”라 불림).

4.2.2. Express Middleware

미들웨어는 request, response, 애플리케이션의 요청-응답 주기 중 그 다음의 미들웨어 함수에 대한 액세스 권한을 갖는 함수

1) Middleware 작성

  • 사용자가 Middleware를 작성할 수 있음
  • next() 메서드를 통해 다음 미들웨어 실행
    • next 메서드의 인자로 ’route’ 입력 시 다음 라우터의 미들웨어 실행
  • Source Code

4.2.3. Third-Party Middleware

Express 앱에 남이 만든 기능을 추가할 수 있음

1) body-parser

2) compression

  • Node.js 모듈의 일종
  • 웹사이트의 성능 개선을 위한 압축 기능을 제공
    • gzip과 deflate를 지원
      • gzip은 특히 텍스트 파일을 압축하는데에 있어 최상의 성능을 냄 (자바스크립트, HTML, CSS, JSON 등 사이트를 구성하는 거의 모든 요소가 텍스트 콘텐츠)
  • compression의 동작 과정
    1. node.js 웹 서버에서 특정 방식(gzip, deflate)으로 압축을 진행
    2. 데이터를 웹 브라우저에 전송할 때 압축된 데이터와 함께 어떤 방식으로 압축했는지를 전송
    3. 웹 브라우저는 해당 방식으로 압축을 해제한 뒤 사용
  • Source Code
  • Reference

4.3. 정적인 파일 서비스하기

4.3.1. 정적 파일이란

  • 이미지, CSS 파일 및 JavaScript 파일과 같은 파일

4.3.2. Express의 정적 파일 제공

  • Express의 기본 제공 미들웨어 함수인 express.static을 사용
  • 정적 자산이 포함된 디렉토리의 이름을 express.static 미들웨어 함수에 전달하면 파일의 직접적인 제공이 가능
  • Source Code

4.4. 에러 처리

  • 에러를 처리할 때는 HTTP 404 코드로 처리하는 것이 일반적
  • express의 약속 : 4개의 인자가 있는 Middleware는 에러를 위한 함수로 하자

4.4.1. 예제

4.5. Router

  • 소프트웨어가 커지면서 복잡도를 정리할 필요가 있음
  • Route가 많아지면서 정리할 필요가 생김
    • Router를 사용하지 않으면 주소 체계가 변경될 경우 일일히 주소 체계를 변경하는 작업을 해야할 수도 있음

4.5.1. express.Router

  • express.Router 클래스를 통해 모듈식 마운팅 가능한 핸들러를 작성
  • Router 인스턴스는 완전한 미들웨어이자 라우팅 시스템
  • “미니 앱(mini-app)”이라고 부르기도 함
  • 라우터를 만들어서 파일로 분리할 수 있음
  • Reference 및 예제 코드 : Express 공식 문서 - Routing

4.6. 보안

4.6.1. 보안 우수 사례

4.7. Express-generator

4.7.1. Express-generator란

  • Express 환경을 간단하게 구축해주는 npm
    • 쉽게 Node.js 개발을 가능하도록 함

4.7.2. 공식 문서

4.7.3. Express-generator 사용 시 디렉토리 구조

5. Express response

기본적으로 서버에서 response를 처리할 때 Content-Type을 지정해주어야 함

5.1. res.send()

  • 기본적으로 response를 보내는 역할
  • 어떤 데이터를 보내는지 파악을 해서 이에 알맞게 Content-Type을 지정해줌
    • Buffer, String, Object, Array …
  • send에 전해진 argument에 따라서 Content-type이 자동적으로 만들어짐 (Default)

5.2. res.json()

  • 웹개발자들이 데이터를 주고 받을때 보통 RESTful API의 형태로 데이터를 주고 받음 (최근에는 다른 방식도 등장하고 있음)
    • 이때 사용하는 형식은 JSON일 확률이 높음
  • json이 아닌 것도 json 형식으로 바꾸어서 보내줌
  • 즉, Content-type 헤더를 application/JSON으로 고정
  • 결국 res.json()도 마지막에 res.send()를 호출

5.3. res.end()

  • 꼭 쓰지 않아도 됨
  • 데이터가 없을 때, 404를 리턴해주어야 할 때 사용
  • res.json()을 쓰나 res.send()를 쓰나 응답을 종료해주는 역할은 하기 때문에 굳이 명시적으로 표시해줄 필요는 없음

Reference

Express res.send() vs res.json() vs res.end() 비교

5. 소스코드


Express Hello World 예제

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

app.get("/", (req, res) => res.send("Hello World!"));

app.listen(3000, () => console.log("Example app listening on port 3000!"));

기본 라우팅 구조

app.METHOD(PATH, HANDLER);

파라미터 전달 예제

app.get("/page/:pageId", function (request, response) {
  response.send(request.params);
});

Redirect 예제

res.redirect("/foo/bar");
res.redirect("http://example.com");
res.redirect(301, "http://example.com");
res.redirect("../login");

body-parser 예제

// import
var bodyParser = require('body-parser');

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }));

// built-in parser
app.use(express.json())

// get body's parameter
app.post('/page', function(req, res) => {
  console.log(req.body)
})

compression 예제

// import
var compression = require("compression");

// use
app.use(compression());

Middleware 작성 예제

app.get(
  "/user/:id",
  function (req, res, next) {
    // if the user ID is 0, skip to the next route
    if (req.params.id == 0) next("route");
    // otherwise pass the control to the next middleware function in this stack
    else next(); //
  },
  function (req, res, next) {
    // render a regular page
    res.render("regular");
  }
);

// handler for the /user/:id path, which renders a special page
app.get("/user/:id", function (req, res, next) {
  res.render("special");
});

정적 파일 서비스 예제

// public이라는 이름의 디렉토리에 포함된 이미지, CSS 파일 및 JavaScript 파일을 제공
app.use(express.static("public"));

에러 처리 예제

// 에러 핸들러
app.use(function (err, req, res, next) {
  console.error(err.stack);
  res.status(500).send("Something broke!");
});

// 404 처리
app.use(function (req, res, next) {
  res.status(404).send("Sorry cant find that!");
});

Express Generater 활용 시 디렉토리 구조 (예시)

.
├── app.js
├── bin
│   └── www
├── package.json
├── public
│   ├── images
│   ├── javascripts
│   └── stylesheets
│       └── style.css
├── routes
│   ├── index.js
│   └── users.js
└── views
    ├── error.pug
    ├── index.pug
    └── layout.pug

7 directories, 9 files

6. 참고자료

6.1. 생활코딩 - Express 프레임워크

WEB3 - Express

6.2. Node.js - Express 공식 문서

Express - Node.js web application framework