웹 서비스 개발(FB,BE,SERVER,DB)/Node.js

6. Express_Server

Zoo_10th 2024. 3. 15.

1. NPM(Node Package Manager)

1-1. npm이란

npm은 노드(Node.js) 패키지 매니저로, 다른 개발자들이 개발한 소스 코드와 모듈을 중앙 저장소에서 제공하고 관리하는 도구이다. 이를 통해 개발자들은 이미 만들어진 코드를 활용하여 개발 과정을 더 효율적으로 진행할 수 있으며, 코드의 재사용성을 높일 수 있다. 또한, npm은 오픈 소스 커뮤니티를 지원하고 발전시키는 핵심 도구 중 하나이다.

1-1-1. 핵심 개념

 - 패키지(Packages)

1) 패키지는 npm 저장소에 업로드된 노드 모듈을 나타낸다.

2) 이러한 패키지들은 개발자들이 필요한 기능을 손쉽게 가져와 사용할 수 있다.

3) 패키지들은 버전 관리를 통해 업데이트되며, 프로젝트에서 사용되는 패키지의 버전을 명시하여 안정적인 개발 환경을 유지할 수 있다.

 - 의존 관계(Dependencies)

1) 패키지는 다른 패키지에 의존할 수 있다.

2) 이러한 의존 관계를 통해 필요한 패키지들을 프로젝트에 쉽게 추가하고 관리할 수 있다.

3) 패키지의 의존성 관리를 통해 버전 충돌 등을 방지할 수 있다.

 - 사용 및 관리

1) npm은 명령 줄 인터페이스를 통해 패키지를 검색하고 설치하는 기능을 제공한다.

2) 개발자는 npm install 명령을 사용하여 프로젝트에 필요한 패키지를 설치할 수 있다.

3) 또한, package.json 파일을 통해 프로젝트의 의존성과 스크립트 등을 관리할 수 있으며, 이 파일은 프로젝트의 설정과 정보를 정의하는 중요한 역할을 한다.

1-2. package.json

package.json은 현재 프로젝트에 대한 정보와 사용중인 패키지에 대한 정보를 담고 있는 파일이다. 이 파일은 노드(Node.js)프로젝트를 관리하고 빌드하기 위한 중요한 역할을 한다.

package.json을 사용하여 프로젝트의 설정, 의존성 관리, 스크립트 실행 등을 정의할 수 있다.

1-2-1. 주요 내용

1) 프로젝트 정보: 프로젝트의 이름, 버전, 설명, 저작권 정보 등과 같은 프로젝트에 대한 기본 정보를 포함한다.

2) 의존성 관리: 프로젝트가 사용하는 외부 패키지들과 그 버전을 명시한다. 이를 통해 프로젝트의 의존성을 관리하고, 다른 개발자나 환경에서 동일한 패키지 버전을 설치하여 일관성을 유지할 수 있다.

3) 스크립트 정의: 프로젝트 빌드, 실행, 테스트 등과 같은 스크립트를 정의하고 실행할 수 있다. 이를 통해 개발자는 명령어 한 줄로 다양한 작업을 수행할 수 있다.

1-2-2. 중요성

package.json 파일은 프로젝트를 공유하거나 협업할 때 중요한 역할을 한다. 또한, 프로젝트의 의존성을 명시하여 버전 관리를 하기 때문에, 다른 환경에서 프로젝트를 재현하거나 패키지를 업데이트할 때 유용하다. 프로젝트를 시작할 때 npm init 명령을 사용하여 package.json 파일을 생성하고 필요한 정보를 입력하는 것이 일반적이다.

1-2-3. package.json의 속성

1) name

 - 패키지의 이름을 나타낸다. 고유한 이름이어야 하며, npm 저장소에서 다른 패키지들과 중복되지 않아야 한다. 대소문자, 하이픈(-), 언더스코어(_)를 포함할 수 있다.

2) version

 - 패키지의 현재 버전을 나타낸다. 버전은 Semantic Versioning (Semver) 규칙에 따라 관리된다. 주로 세 자리 숫자로 이루어진 버전 번호(예: "1.2.3") 형식을 사용한다.

3) main

 - 패키지의 주 진입점 파일을 지정한다. 이 파일은 모듈로서 다른 코드에서 불러올 때 사용됩니다. 주로 Node.js 환경에서 사용된다.

4) scripts

 - 사용자 정의 스크립트 명령어를 정의하는 객체이다. 예를 들어 "start" 스크립트를 설정하면 npm start 명령어로 해당 스크립트를 실행할 수 있다. 테스트, 린팅 등 프로젝트에 필요한 다양한 작업을 자동화할 수 있다.

5) repository

 - 패키지의 소스 코드를 호스팅하는 Git 저장소 주소를 나타낸다. 이 정보를 통해 다른 개발자들은 소스 코드에 접근하고 협력할 수 있다.

6) keywords

 - 패키지에 대한 키워드를 나타낸다. 이 키워드들은 npm 공식 홈페이지에서 패키지를 검색하고 분류하는 데 사용된다.

7) license

 - 패키지의 라이선스 정보를 나타낸다. 이 정보는 패키지를 사용할 때 라이선스 준수를 확인하는 데 도움을 준다. 일반적으로 SPDX 라이선스 식별자를 사용한다.

1-3. Package Install

1-3-1. express 설치

이 명령을 실행하면 Express 패키지가 프로젝트에 설치되며, 이 정보는 package.json 파일의 dependencies 섹션에 Express 패키지의 이름과 버전이 추가된다.

1-3-2. node_modules

npm install 명령을 실행하면 프로젝트 폴더 내에 node_modules라는 디렉토리가 생성된다. 이 디렉토리에는 설치한 패키지와 해당 패키지의 의존성이 저장된다. 예를 들어, Express를 설치할 때 Express와 Express에 의존하는 다른 패키지들이 모두 이 디렉토리에 저장된다.

1-3-3. package-lock.json

npm install 명령을 실행하면 package-lock.json 파일도 생성된다. 이 파일은 패키지 간 의존 관계를 명확하게 표시하고 패키지 버전을 고정하는 데 사용된다. 이를 통해 다른 개발자들이 동일한 환경에서 프로젝트를 실행하고 패키지 버전 충돌을 방지할 수 있다.

1-3-4. 여러 패키지 동시 설치하기

여러 개의 패키지를 동시에 설치하려면 아래와 같이 패키지 이름을 나열하여 npm install 명령을 실행한다.

npm install 패키지1 패키지2 패키지3

1-4. Package Version

1-4-1. SemVer 버저닝

패키지의 버전 관리는 SemVer(유의적 버저닝) 방식을 따른다. 이 방식은 패키지의 버전을 명확하게 정의하고 관리하기 위한 규칙을 제공한다. SemVer는 다음과 같이 세 가지 주요 버전으로 구분된다.

1)  Major (주 버전): 하위 버전과 호환되지 않는 주요 변경 사항이 있을 때 증가한다. 이는 API 변경, 중요한 기능 변경, 하위 버전과의 호환성 손상을 의미한다.

2) Minor (부 버전): 하위 버전과 호환되는 새로운 기능이 추가되었을 때 증가한다. 이는 새로운 기능의 추가, API 확장, 하위 버전과의 호환성 유지를 의미한다.

3) Patch (수 버전): 기존 기능에 대한 버그 수정 또는 보완 사항이 있을 때 증가한다. 이는 기능 개선 및 버그 수정을 의미한다.

패키지의 버전은 보통 MAJOR.MINOR.PATCH 형식으로 표현됩니다. 예를 들어, 1.2.3 버전은 주 버전이 1, 부 버전이 2, 수 버전이 3임을 나타난다.

1-5. 기타 npm 명령어

1) npm outdated: 패키지 업데이트 가능성을 확인하기 위해 사용한다. 어떤 패키지가 현재 버전보다 새로운 버전이 있는지 확인할 수 있다.

2) npm update: 패키지 업데이트를 실행합니다. package.json 파일의 내용에 따라 패키지를 업데이트 한다.

3) npm uninstall 패키지명: 패키지를 삭제합니다. 또는 npm rm 패키지명 명령어를 사용할 수도 있다.

4) npm search 검색어: npm 패키지를 검색할 수 있다. 이 명령어를 통해 패키지를 검색하고 관련 정보를 확인할 수 있다. 검색 결과는 npmjs.com에서도 확인할 수 있다.

5) npm info 패키지명: 특정 패키지의 세부 정보를 확인한다. 이를 통해 패키지의 버전, 라이선스, 종속성 등을 파악할 수 있다.

6) npm login: npm에 로그인하기 위한 명령어이다. npmjs.com에서 회원가입이 필요하며, 로그인하면 패키지를 배포하거나 관리할 수 있다.

7) npm whoami: 현재 사용자가 누구인지 확인합니다. 로그인한 사용자의 정보를 보여준다.

8) npm logout: 로그인한 계정을 로그아웃한다.

9) npm version 버전: 패키지의 버전을 올린다. 이 명령어를 실행하면 package.json 파일의 버전 정보를 업데이트하고, 변경 사항을 Git에 커밋할 수 있다.

10) npm deprecate [패키지명][버전] [메시지]: 패키지를 설치할 때 경고 메시지를 띄우도록 설정한다. 이를 통해 오류가 있는 패키지를 사용하는 사용자에게 경고를 보낼 수 있다.

11) npm publish: 자신이 만든 패키지를 npm 저장소에 배포한다.

12) npm unpublish --force: 자신이 만든 패키지를 배포 중단한다. 이 명령어를 사용하면 배포한 패키지를 삭제할 수 있다. 단, 배포 후 24시간 내에만 가능하며, 다른 사람이 패키지를 사용 중일 경우 문제가 될 수 있으므로 주의가 필요하다.

 - 이 외에도 npm의 다양한 명령어와 옵션에 대한 정보는 npm 공식 문서의 CLI Commands에서 확인할 수 있다.

2. Express

2-1. Express

Express는 Node.js를 위한 인기있는 웹 프레임 워크이다. 이는 Node.js의 기본 HTTP 기능을 확장하고, 웹 애플리케이션 개발을 보다 쉽고 효율적으로 만들어준다. 각 단계를 통해 간단한 Express 기반 웹 서버를 만드는 방법을 설명한다.

2-1-1. package.json 생성

1) package.json은 프로젝트의 메타데이터와 의존성을 관리하는 파일이다.

2) npm init 명령어를 사용하여 package.json을 자동으로 생성할 수 있다.

3) 개발중 코드 변경이 있을 때 서버를 자동으로 재시작해주는 nodemon도 설치할 수 있다.

2-1-2. app.js 작성

1) app.js는 Express 애플리케이션의 핵심 파일이다.

2) 서버가 사용할 포트를 app.set('port', 포트)를 통해 지정한다.

3) app.get('주소', 라우터)를 사용하여 GET 요청에 대한 라우트를 설정한다.

4) app.listen('포트', 콜백)을 사용하여 서버를 시작하고 특정 포트에서 수신한다.

2-1-3. 서버실행을 위한 디렉토리 구조

1) app.js: 서버의 메인 스크립트 파일.

2) public: 클라이언트가 접근할 수 있는 정적 파일(이미지, CSS, JS 등)을 저장한다.

3) views: 템플릿 파일을 저장합니다. Express는 EJS, Pug와 같은 템플릿 엔진을 지원한다.

4) routes: 라우팅 로직을 모아둡니다. 각 URL 경로에 대한 요청 처리를 정의한다.

5) 필요한 경우, models 디렉토리를 추가하여 데이터베이스와의 상호작용을 관리한다.

Express Server 실행

1) npm start 명령어를 통해 서버를 시작한다. 이 명령어는 package.json 파일의 scripts 섹션에 정의된 start 스크립트를 실행한다.

2-1-4. HTML 서빙

1) res.sendFile 메서드를 사용하여 HTML 파일을 클라이언트에 제공할 수 있다. 이를 통해 서버가 HTML페이지를 클라이언트에 전송한다.

Express를 사용하면 이러한 모든 과정을 더욱 체계적이고 유연하게 관리할 수 있으며, Node.js 웹개발의 생산성과 유지보수성을 크게 향상시킬 수 있다.

<html>
<head>
  <meta charset="UTF-8" />
  <title>익스프레스 서버</title>
</head>
<body>
  <h1>익스프레스</h1>
  <p>배워봅시다.</p>
</body>
</html>

index.html

const express = require('express');
const path = require('path');

const app = express();
app.set('port', process.env.PORT || 3000);

app.get('/', (req, res) => {
  // res.send('Hello, Express');
  res.sendFile(path.join(__dirname, '/index.html'));
});

app.listen(app.get('port'), () => {
  console.log(app.get('port'), '번 포트에서 대기 중');
});

app.js

2-2. Middleware

미들웨어는 Express 애플리케이션의 핵심적인 부분으로, 요청(request)과 응답(response) 사이의 중간 처리 단계에 해당한다. 미들웨어를 사용하면 요청을 받고 응답을 보내기 전에 다양한 작업을 수행할 수 있다.

2-2-1. 미들웨어의 기본 개념

1) 기능: 요청 및 응답 객체에 접근하여, 요청 파이프라인 중간에 실행되는 함수이다.

2) 사용법: app.use(미들웨어)를 사용하여 미들웨어를 애플리케이션에 추가한다.

3) 실행 순서: 미들웨어는 등록된 순서대로 위에서 아래로 실행된다.

4) 매개변수: 각 미들웨어 함수는 req (요청 객체), res (응답 객체), next (다음 미들웨어를 호출하는 함수)를 매개변수로 받는다. 

5) next 함수: next() 함수를 호출하면 흐름이 다음 미들웨어로 이동한다.

2-2-2. 에러 처리 미들웨어

1) 에러 처리 미들웨어는 일반 미들웨어와 유사하지만, 매개변수로 error를 추가로 받는다.

2) 일반적으로 모든 미들웨어 후에 배치되어, 앞선 미들웨어에서 발생한 에러를 처리한다.

3) 형식 : app.use((err, req, res, next) => { /* 에러 처리 로직 */ });

2-2-3. 주요 미들웨어 예시

1) morgan: HTTP 요청 로그를 기록하는 미들웨어이다.

2) cookie-parser: 쿠키 데이터를 파싱하여 req 객체에 추가한다.

3) express-session: 세션 관리를 위한 미들웨어이다. 사용자별로 서버에 정보를 저장할 수 있다.

2-2-4. 미들웨어 특성

미들웨어는 req, res, next를 매개변수로 가지는 함수로, Express 애플리케이션의 요청-응답 사이클에서 중간 단계를 처리한다.

2-2-5. next 함수의 사용

1) next 함수를 호출하면 처리 흐름이 다음 미들웨어로 넘어간다.

2) next를 호출하지 않으면 요청 처리가 멈추고 응답이 전송되지 않는다.

3) next에 에러를 인수로 넣으면 에러 처리 미들웨어로 바로 이동한다.

2-2-6. 미들웨어간 데이터 전달

1) req 또는 res 객체에 값을 추가하여 데이터를 전달할 수 있다.

2) res.locals 객체를 사용하여 요청 동안 데이터를 전달하는 방법이 일반적이다.

2-2-7. 미들웨어 확장하기

미들웨어 내부에 다른 미들웨어를 넣어서 기능을 확장할 수 있다.

애플리케이션의 기능을 향상시키고, 보다 효율적인 요청 처리가 가능하다. 각 미들웨어는 설치 후 app.use로 애플리케이션에 추가하며, 내부적으로 next를 호출하여 처리를 다음 미들웨어로 넘길 수 있다. 이런 방식으로 Express는 강력한 확장성과 유연성을 제공한다.

2-3. 주요 미들웨어

2-3-1. dotenv

1) 목적: .env 파일을 사용하여 환경변수를 관리한다. 이 방법은 중요한 정보를 소스 코드에 직접 적지 않고 보안을 유지할 수 있게 해준다.

2) 작동 방식: .env 파일에서 키-값 쌍을 읽어 process.env에 할당합니다. 예를 들어, COOKIE_SECRET=cookiesecret라고 적으면 process.env.COOKIE_SECRET에 cookiesecret 값이 할당 된다.

3) 보안: 중요한 비밀 키들을 소스 코드에서 분리하여 관리함으로써 보안을 강화할 수 있다. 소스 코드가 유출되더라도 .env 파일이 분리되어 있으면 비밀 키들은 안전하다.

2-3-2. morgan

1) 기능: 서버로 들어오는 요청과 응답을 로그로 기록해주는 미들웨어이다.

2) 로그 레벨: dev, tiny, short, common, combined 등 다양한 로그 레벨을 선택할 수 있다.

3) 사용 예시: GET / 200 51.267 ms – 1539는 요청 방식, 경로, 상태 코드, 응답 시간, 응답 크기를 나타낸다. 개발 환경에서는 dev, 배포 환경에서는 combined를 주로 사용한다.

4) 더 자세한 로그: 보다 상세한 로깅을 위해서는 winston 같은 패키지를 사용할 수 있다.

2-3-3. static

1) 기능: 정적 파일(이미지, CSS, JavaScript 파일 등)을 제공하는 미들웨어이다.

2) 사용법: 정적 파일이 위치한 디렉토리 경로를 인수로 제공한다.

3) 장점: 파일이 있으면 자동으로 응답하고, 없으면 next()를 호출해 다음 미들웨어로 넘어간다.

4) 보안: 요청 URL과 실제 파일의 저장 경로를 다르게 설정함으로써 서버의 구조를 숨기고 보안을 강화할 수 있다.

2-3-4. body-parser

1) 기능: 요청 본문을 파싱하여 req.body에 데이터를 넣어주는 미들웨어이다.

2) 지원 형식: json 미들웨어는 JSON 형식의 요청을, urlencoded 미들웨어는 URL 인코딩된 폼 데이터를 파싱한다.

3) 사용법: PUT, PATCH, POST 요청에서 req.body를 통해 클라이언트에서 보낸 데이터에 접근할 수 있다.

4) 특이 사항: 버퍼 데이터나 텍스트 데이터 처리를 위해 body-parser를 직접 설치해야 하며, 멀티파트 데이터(이미지, 동영상 등)의 경우 multer 같은 다른 미들웨어를 사용한다.

2-3-5. cookie-parser

1) 기능: 요청 헤더의 쿠키를 파싱하여 req.cookies에 저장하는 미들웨어이다.

2) 보안 기능: 비밀 키를 사용하여 서명된 쿠키를 생성하고 검증할 수 있다. 이를 통해 해당 쿠키가 서버에서 생성된 것임을 확인할 수 있다.

3) 쿠키 옵션: expires, domain, httpOnly, maxAge, path, secure, sameSite 등 다양한 쿠키 옵션을 설정할 수 있다.

4) 쿠키 삭제: clearCookie 메서드를 사용하여 쿠키를 삭제할 수 있다.

2-3-6. express-session

Express-session은 세션 관리를 위한 미들웨어로, 사용자별로 서버에 데이터를 저장할 수 있게 해준다. 

1) 세션 쿠키 설정: secret은 쿠키를 암호화하는 데 사용되며, cookie는 세션 쿠키의 옵션을 설정한다. 세션 쿠키는 암호화된 후 클라이언트에 전송된다.

2) resave: 요청이 왔을 때 세션에 변경 사항이 없더라도 세션을 다시 저장할지 여부를 설정한다.

3) saveUninitialized: 세션에 저장할 내용이 없더라도 초기화되지 않은 세션을 강제로 저장할지 결정한다.

4) 수동 저장: req.session.save()를 사용하여 수동으로 세션을 저장할 수 있다.

2-3-7. 멀티파트 데이터 형식

1) multipart/form-data 형식의 데이터는 body-parser로 처리할 수 없다.

2) 이러한 데이터를 처리하기 위해 multer 미들웨어를 사용한다.

2-3-8. multer 설정

1) multer를 설정하여 파일 업로드를 관리한다.

2) diskStorage를 사용하여 파일을 서버의 디스크에 저장한다.

3) destination은 파일이 저장될 경로, filename은 저장될 파일 이름을 설정한다.

4) limits를 통해 파일 크기나 개수 등을 제한할 수 있다.

5) 실제 서버 운영 시에는 S3 같은 클라우드 스토리지 서비스에 파일을 저장하는 것이 좋다.

2-3-9. multer 미들웨어 사용

1) single, none, array, fields 등 여러 타입의 미들웨어를 사용할 수 있다.

2) single은 단일 파일, array과 fields는 여러 파일을 처리한다.

3) 업로드된 파일 정보는 req.file 또는 req.files에 저장된다.

728x90

'웹 서비스 개발(FB,BE,SERVER,DB) > Node.js' 카테고리의 다른 글

Express_Server2  (0) 2024.03.18
5. Node.js WebServer 2  (0) 2024.03.13
4. Node.js WebServer  (0) 2024.03.12
3. Node.js_Basic2  (0) 2024.03.11
2. Node.js_Basic  (0) 2024.03.11

댓글