[TIL] Day 19 : Node.js, express.js 입문

Q·2024년 5월 13일

TIL

목록 보기
20/59

STEP 0

  • node.js 설치 (npm 자동 설치됨)
  • yarn 설치 npm install -g yarn
  • node.js란?

    원래는 JavaScript라는 언어가 브라우저 환경에서만 실행될 수 있었는데(애초에 브라우저에서 동작하도록 만든 언어다. 때문에 브라우저는 자체적으로 JS 엔진을 가지고 있다.), Google이 Chrome에서 사용하는 JS 엔진 V8을 오픈소스로 개발하였고, 이걸 기반으로 브라우저가 아닌 로컬 환경에서도 JS를 해석하고 실행할 수 있도록 만든 런타임 환경이 Node.js이다.
    즉, Chrome V8 JavaScript engine으로 빌드된 JavaScript 런타임.

  • npm이란?

    Node package manager의 줄임말. Node.js가 제공하는 여러 패키지들을 설치 및 관리할 수 있게 해준다.

  • yarn이란?

    페이스북에서 만든 JS package manager이다. npm에서 부족한 속도, 안정성, 보안성 등을 개선했다.

  • npm 대신 yarn을 쓰는 이유는?

    • 패키지를 다운로드 하는 과정에서 보안 검사를 수행한다.
    • 병렬 처리를 도입하여, 패키지 설치 속도가 npm보다 빠르다.
    • dependency를 가지는 다른 패키지들을 모두 설치를 하는 npm과 달리, yarn.lock이나 package.json 파일에 있는 것들만 설치를 한다. 또한 버전의 차이로 인해 생기는 버그를 방지한다.

    기능면에서는 아주 큰 차이가 존재하지는 건 아니지만, 일단은 강의 내용을 따라 yarn을 사용하도록 하겠다.

STEP 1

새로운 프로젝트를 시작하기 위한 첫 단추.
package.json 파일을 생성한다.
npm -> npm init or npm init -y
yarn -> yarn init or yarn init -y

뒤의 -yyarn init 명령 실행시 원래는 프로젝트명이나 버전 등을 물어보는데 그런 것들을 물어보지 않고 전부 default 값으로 설정해주는 옵션

package.json 은 yarn 으로 설치할 패키지에 대한 정보가 들어간다.
패키지명, 프로젝트 버전, Github URL등 프로젝트와 관련된 다양한 정보를 설정할 수 있다.

{
  "name": "project-name",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT"
}

프로젝트명은 따로 설정하지 않으면 default 값이 terminal의 현재 위치 폴더 이름이 된다.

{
	"name": "spa-shop",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "type": "module"
}

여기서 별다른 지정을 해주지 않으면 default로 commonJS module을 쓰게 된다.
따라서 ES6 module을 사용하려면 "type": "module" 을 추가해줘야 한다.
패키지를 설치하게 되면 밑에

  "dependencies": {
      "패키지1 이름": "패키지1 버전",
      "패키지2 이름": "패키지2 버전",
      ...
   }

가 추가된다. 말 그대로, 이 프로젝트가 어떤 패키지에 dependency가 있는지를 보여준다. (버전까지 보여주는 건 덤)
drawing

STEP 2

패키지를 설치 (express, mongoose)
npm -> npm install express mongoose
yarn -> yarn add express mongoose

  • 저렇게 쓰면 express와 mongoose 두 개가 설치된다. 한꺼번에 더 설치하려면 뒤에 이름을 띄어쓰기와 함께 계속 이어 쓰면 된다.

  • 패키지가 설치되면, STEP 1에서 언급했듯 package.json 파일 속 "dependencies" 에 패키지 이름과 버전이 추가가 될 뿐만 아니라
    node_modules 폴더와 yarn.lock 파일이 생성된다.

  • node_modules 란?

    yarn add 명령어를 통해 설치하려던 패키지 뿐만 아니라 그 패키지가 의존하는 다른 패키지들도 모두 설치되는데, 그 패키지들이 저장되는 폴더이다.
    drawing
  • yarn.lock 이란?

    package.json의 "dependencies" 목록에 추가된 패키지들이 yarn add 명령어를 통해 같이 설치된 패키지들 과의 dependency 관계가 정리된 파일이다.
  • 따라서 코드에서 사용한 패키지에 대한 정보는 모두 package.jsonyarn.lock 파일에 정리가 되어있으므로 배포할 때는 node_modules 폴더를 제외하고 배포하면 된다.

    파일을 받을 사람은 yarn 이라고 명령어를 치면 package.jsonyarn.lock에 저장된 패키지를 모두 받을 수 있다.

    이렇게 하는 이유는, 사용중인 환경에 맞는 파일들이 설치되도록 하기 위함이다. (OS 차이 등)

  • express 란?

    Node.js의 웹 프레임워크. 백엔드 서버를 빠르고 간편하게 만들 수 있게 도와준다.

    장점1.   미들웨어(Middleware)를 지원한다.

    장점2.   개발자 커뮤니티가 매우 활발하다.

  • mongoose 란?

    NoSQL 중 많이 쓰이는 MongoDB 라는 데이터베이스를 Node.js로 사용할 수 있도록 하는 확장 모듈 중 하나이다. ODM(Object-Document Mapping)이라고 한다. 말 그대로 JS의 Object를 MongoDB의 Document로 Mapping 시켜주는 역할이다.

    MongoDB는 MongoDB Cloud Service를 이용하도록 하겠다.
    그리고 MongoDB도 유용한 Client가 있는데, Studio 3T 라는 툴이다. GUI라 직관적이고 쉽게 DB에 접근하고 다룰 수 있다.

STEP 3

Express.js로 간단한 백엔드 서버 구현

// app.js

// express 모듈을 가져온다
import express from "express";

// express 애플리케이션을 생성하고 app 변수에 할당한다
const app = express();

// 웹 서버가 사용할 포트 번호를 PORT 상수에 저장한다.
const PORT = 3000;

// 루트 경로 "/"로 GET 요청이 오면 어떻게 처리를 할지에 대한 express 애플리케이션 핸들러를 정의한다.
app.get("/", (req, res) => {
  res.send("Hello World!");
});

// express 애플리케이션을 PORT 변수에 지정된 포트 번호에서 대기하도록 한다. 서버가 시작되면 console에 메시지를 출력한다.
app.listen(PORT, () => {
  console.log(PORT, "포트로 서버가 열렸어요!");
});

이 코드를 실행하면, 로컬 서버가 3000번 포트에서 실행되고, 브라우저에서 주소창에 http://localhost:3000 을 입력하면 "Hello World!" 메시지를 볼 수 있다.

STEP 4

Router 설정

  • Router란? 는 클라이언트의 요청을 쉽게 처리 할 수 있게 도와주는 Express.js의 기본 기능중 하나이다.
    일반적으로 Router는 아래와 같은 구조를 가진다.
	router.METHOD(PATH, HANDLER);

쉽게 말하자면,

'router'에 'PATH' 라는 경로에 대한 'METHOD' 라는 요청이 오면, 'HANDLER'를 실행해줘.

라는 뜻이다.

  • router : Express.js의 라우터를 정의하기 위해 사용
  • METHOD : HTTP Method (ex: get, post, put, patch, delete …)
  • PATH : 실제 서버에서 API를 사용하기 위한 경로 (ex: users, posts …)
  • HANDLER : route가 일치할 때 실행되는 함수

예시

routes 라는 이름의 폴더와 그 폴더 안에 goods.js 파일 생성 후
express에서 제공되는 Router 함수를 사용해 express Router를 생성

// routes/goods.js

import express from "express";

// Express.js의 라우터를 생성합니다.
const router = express.Router();

// localhost:3000/api/ 주소로 GET 요청
router.get('/', (req, res) => {
  res.json('default url for goods.js GET Method');
});

// localhost:3000/api/about 주소로 GET 요청
router.get('/about', (req, res) => {
  res.json('goods.js about PATH');
});

// 작성한 Router를 app.js에서 사용하기 위해 export
export default router;

goods.js 파일에서 export한 Router를 app.js의 middleware에 사용

// app.js

import express from "express";
import goodsRouter from "./routes/goods.js";

const app = express();
const PORT = 3000;

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

// localhost:3000/api -> goodsRouter
app.use("/api", [goodsRouter]);

app.listen(PORT, () => {
  console.log(PORT, "포트로 서버가 열렸어요!");
});

이렇게 하면, http://localhost:3000 뒤에 /api 로 시작되는 주소는 routes/goods.js 에 있는 Router Middleware를 통해 처리된다.

STEP 5

API client

웹브라우저를 통한 html 환경이 아니더라도 개발단계에서 우리가 작성한 API의 요청을 확인하거나 test 해볼 수 있는 client tool이다.

대표적으로 Insomnia, Postman 이 있는데, 앞으로 우리는 insomnia를 사용할 것이다.

STEP 6

request, response 의 사용 방법

request

클라이언트가 서버에게 전달하려는 정보나 메시지를 담는 객체
url, method, header, query parameter, body data 등을 포함

req.app : express.js의 app 객체에 접근
req.ip : 요청한 클라이언트의 ip 주소가 담긴 객체
req.body : express.json() 라는 전역 Middleware를 이용해서 사용가능

app.post("/", (req, res) => {
	const ReqBody = req.body;
    return res.status(201).json({});
});

클라이언트가 POST 또는 PUT의 Method로 request를 보내면서 body에 데이터를 삽입하였을 때, 즉 데이터를 생성(Create)하거나 수정(Update)이 필요한 데이터를 전달하기 위해 사용한다.
Key-Value의 데이터 형식을 가지고 있으며 대표적으로 JSON 형태이다.

req.params : 라우터 parameters에 대한 정보가 담긴 객체.
url에 원하는 데이터를 삽입하여 전달한다.
특정 게시글을 선택하거나 게시글의 상세 정보 조회 등 명확한 리소스를 지정해야할 때 사용한다.

app.get("/:name", (req, res) => {
	const { name } = req.params;
    return res.status(200).json({});
});

req.query : url에 원하는 Key-Value를 "?" 기호 뒤에 query string으로 삽입하여 데이터를 전달한다. 주로 서버의 리소스를 필터링하거나 정렬하는 등 웹 페이지에 특정한 옵션을 설정할 때 사용한다.
ex) https://sparta.com?name=홍길동&age=29
ex) https://sparta.com/posts?sort=desc&page=3&limit=20

app.get("/", (req, res) => {
	const ReqQuery = req.query;
    return res.status(200).json({});
});

req.cookies : Cookie 정보가 담긴 객체. cookie-parser 라는 middleware를 이용하여 사용 가능
req.get(Header) : 클라이언트가 전달한 Header의 값을 조회


response

서버에서 클라이언트로 응답 메시지를 전송시켜주는 객체.
status code, response data, response header 등을 포함한다.

res.app : express.js의 app 객체에 접근한다.
res.status(코드) : http status code를 지정한다.
ex)   200 : OK (The request succeeded.)
        201 : Created (리소스가 성공적으로 생성되었음. 주로 POST에 대한 res)
        400 : Bad Request (요청 실수)
        404 : Not Found (요청한 리소스가 서버에 존재하지 않음)
      express에서 상태코드를 명시하지 않을 시, default는 200이다.

res.send(데이터) : 데이터를 포함하여 response를 전달 (일반적으로 String)
res.json(JSON) : JSON 형식으로 response를 전달
res.end() : 데이터 없이 response를 전달
res.redirect(주소) : 리다이렉트할 주소와 함께 response를 전달
res.cookie(Key, Value, Option) : 쿠키를 설정할 때 사용
res.clearCookie(Key, Value, Option) : 쿠키를 제거할 때 사용

const router = express.Router();

router.get("/api/news/:newsId", (req, res) => {
	const params = req.params;
    const newsId = params.newsId;
    
    console.log("클라이언트로 부터 전달받은 뉴스 ID:", newsId);
   	return res.status(200).json({
    	data: "뉴스 세부 조회 API 입니다.",
  	});
});

0개의 댓글