Express로 웹 서버 만들기
💡 Express.js란?
Node.js에서 웹 애플리케이션 또는 API 서버를 구축하는데 가장 많이 사용되는 대표적인 프레임워크이다.
공식문서
Express.js를 사용하기 위해서는 Node.js가 먼저 설치되어 있어야 한다.
npm init
// y는 "yes"를 의미함
npm init -y
각 항목에 맞게 내용을 작성하면 package.json 파일이 생성된다.
package.json은 npm(node package manager)를 통해 추가되는 패키지들의 버전과 의존성 정보를 관리하는 파일이다.
항목 | 내용 |
package name | 패키지 이름으로 프로젝트 혹은 현재 애플리케이션 이름을 말한다. |
version | 패키지, 프로젝트, 애플리케이션 버전을 말한다. |
description | 패키지, 프로젝트, 애플리케이션 설명을 말한다. |
entry point | 프로젝트에서 가장 먼저 실행되는 자바스크립트 실행파일로 웹 서버의 경우 index.js 혹은 app.js로 지정해준다. |
test command | 코드 테스트 시에 입력해 줄 명령어로, 사용하지 않을 경우 빈 값으로 지정된다. |
git repository | 코드를 저장해둔 깃(Git) 저장소 주소로 사용하지 않을 경우 빈 값으로 지정된다. |
keywords | 패키지, 프로젝트, 애플리케이션의 검색을 위한 키워드 |
license | 패키지, 프로젝트, 애플리케이션의 라이선스로 기본값은 ISC(Internet Systems Consortium)에서 허용한 자유 소프트웨어 라이센스 |
npm install express
Node.js를 설치하고 package.json 파일을 생성한 후 express를 설치한다.
express가 설치되면 프로젝트 폴더에 node_modules라는 폴더가 생성되며, 자동으로 express 패키지가 참조하고 있는 다른 npm 패키지들이 설치된다.(패키지 의존성)
// 1. 모듈 가져오기
const express = require("express");
const path = require("path");
// 2. 앱 설정
const app = express();
app.set("port", process.env.PORT || 3000);
// 3. 라우트 설정
app.get("/", (req, res) => {
res.send("Hello, Express");
});
// 4. 서버 시작
app.listen(app.get("port"), () => {
console.log(app.get("port"), "번 포트에서 대기 중");
});
index.js 혹은 app.js에 다음과 같이 입력하고 터미널 창을 열어 node index.js(app.js) 명령어를 통해 실행한다.
http://localhost:포트번호를 입력하면 아래와 같이 나오면 성공이다.
req, res 객체
Express의 req, res 객체는 http 모듈의 req, res 객체를 확장한 것이다.
express에서 기존 http 모듈의 res.writeHead, res.write, res.end 메서드 등을 사용할 수 있다.
express에서 추가적인 기능을 제공하는데 res.send나 res.sendFile 같은 메서드 등을 쓸 수 있다.
⭐️ req
req 객체는 클라이언트의 요청(Request)에 대한 정보를 담고 있다.
- req.app: 현재 요청을 처리하는 Express 애플리케이션 인스턴스를 반환합니다.
- req.baseUrl: 현재 라우트의 URL 경로를 반환합니다.
- req.body: 요청의 본문 데이터를 포함하며, 미들웨어가 필요합니다 (express.json() 등).
- req.cookies: 요청에 포함된 쿠키 객체입니다 (쿠키 파싱 미들웨어 필요).
- req.fresh: 캐싱이 유효한 경우 true를 반환하고, 그렇지 않으면 false를 반환합니다.
- req.hostname: 요청이 들어온 호스트 이름을 반환합니다.
- req.ip: 요청을 보낸 클라이언트의 IP 주소를 반환합니다.
- req.ips: trust proxy가 설정된 경우, X-Forwarded-For 헤더에 설정된 IP 주소 배열을 반환합니다.
- req.method: 요청의 HTTP 메서드 (예: GET, POST, PUT, DELETE 등) 를 반환합니다.
- req.originalUrl: 요청된 원래 URL을 반환합니다.
- req.params: 경로 파라미터 객체입니다.
- req.path: 요청 경로 부분을 반환합니다.
- req.protocol: 요청 프로토콜 (http 또는 https)을 반환합니다.
- req.query: URL 쿼리 문자열 파라미터 객체입니다.
- req.route: 매칭된 현재 라우트 정보입니다.
- req.secure: 요청이 HTTPS로 이루어진 경우 true를 반환합니다.
- req.signedCookies: 서명된 쿠키 객체를 반환합니다 (쿠키 서명 미들웨어 필요).
- req.stale: 캐싱이 유효하지 않은 경우 true를 반환하고, 그렇지 않으면 false를 반환합니다.
- req.subdomains: 서브도메인의 배열을 반환합니다 (주 도메인이 아닌 앞 부분).
- req.xhr: 요청이 AJAX 요청인 경우 true를 반환합니다.
- req.get(header): 특정 HTTP 헤더 값을 반환합니다. 예: req.get('Content-Type').
- req.is(type): 요청의 Content-Type이 특정 타입과 일치하는지 확인합니다. 예: req.is('json').
- req.accepts(types): 클라이언트가 수락 가능한 콘텐츠 유형을 검사합니다. 예: req.accepts(['json', 'html']).
⭐️ res
res 객체는 클라이언트의 응답(Response)에 대한 정보를 담고 있다.
- res.app: 현재 요청을 처리하는 Express 애플리케이션 인스턴스를 반환합니다.
- res.append(field, value): 응답 헤더에 값을 추가합니다.
- res.attachment([filename]): 클라이언트에게 파일 다운로드를 제공합니다.
- res.cookie(name, value, [options]): 쿠키를 설정합니다.
- res.clearCookie(name, [options]): 쿠키를 제거합니다.
- res.download(path, [filename], [callback]): 클라이언트에게 파일을 다운로드하도록 합니다.
- res.end([data], [encoding]): 응답을 종료합니다.
- res.format(object): 요청의 Accept 헤더에 따라 적절한 응답을 보냅니다.
- res.get(field): 지정된 응답 헤더 필드의 값을 반환합니다.
- res.header(name, value): 응답 헤더를 설정합니다.
- res.json([body]): JSON 응답을 보냅니다.
- res.jsonp([body]): JSONP 응답을 보냅니다.
- res.links(links): Link 헤더를 설정합니다.
- res.location(path): Location 헤더를 설정합니다.
- res.redirect([status,] path): 리디렉션합니다.
- res.render(view, [locals], [callback]): 뷰를 렌더링합니다.
- res.send([body]): 응답을 보냅니다.
- res.sendFile(path, [options], [callback]): 파일을 보냅니다.
- res.sendStatus(statusCode): 상태 코드와 해당 상태 메시지를 보냅니다.
- res.set(field, value): 응답 헤더를 설정합니다.
- res.status(code): HTTP 상태 코드를 설정합니다.
- res.type(type): Content-Type 헤더를 설정합니다.
- res.vary(field): Vary 헤더를 설정합니다.
미들웨어
💡 미들웨어는 애플리케이션의 요청-응답 주기에서 특정 작업을 수행하기 위해 사용되는 함수이다. 미들웨어는 요청이 서버에 도착하고, 응답이 클라이언트로 전송되기 전에 중간에서 여러 작업을 처리할 수 있다.(요청 로깅, 인증, 데이터 파싱, 세션 관리 등)
특징
- 순차적 실행 : 요청이 들어오면 등록된 순서대로 미들웨어가 실행됩니다. 각 미들웨어는 next() 함수를 호출하여 다음 미들웨어로 제어를 전달
- 요청 객체와 응답 객체 접근 : 각 미들웨어는 res, req, next 객체에 접근할 수 있어 요청 데이터 조작이나 응답 수정이 가능하다.
- 유연성 : 다양한 기능을 가진 미들웨어를 조합하여 사용하거나, 필요에 따라 커스텀 미들웨어를 작성할 수 있다.
morgan
Morgan은 HTTP 요청 로깅을 위한 미들웨어이다. 요청이 들어올 때마다 로그를 남겨 개발 및 디버깅에 유용하다. 인수로 dev 외에 combined, common, short, tiny 등을 넣을 수 있다.
const morgan = require("morgan");
app.use(morgan('dev'));
body-parser
Body-Parser는 요청 본문을 파싱하여 req.body에 저장해주는 미들웨어이다. 현재는 express에 내장된 기능으로 대체되었다. 폼 전송은 URL-encoded 방식을 주로 사용한다. urlencode 옵션 extended는 false이면 노드의 querystring 모듈을 사용하고 true이면 qs 모듈을 사용해 해석한다.
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
익스프레스는 JSON과 URL-encoded 형식 외에도 Raw, Text 형식의 데이터를 추가로 해석할 수 있다. Raw는 요청의 본문이 버퍼일 때, Text는 텍스트 데이터일 때 해석하는 미들웨어이다.
app.use(express.raw());
app.use(express.text());
dotenv
Dotenv는 환경 변수를 관리하기 위한 미들웨어로, .env 파일에 설정된 변수를 process.env에 로드한다. 민감한 정보를 코드에 직접 작성하지 않고, 환경 변수로 관리할 수 있어 보안에 유리하다. 예를 들어, 데이터베이스 비밀번호나 API 키 등을 .env 파일에 저장한다. .env 파일은 .gitignore에 추가하여 버전 관리 시스템에 노출되지 않도록 한다.
require('dotenv').config();
multer
Multer는 파일 업로드를 처리하기 위한 미들웨어입니다. 주로 폼에서 파일을 업로드할 때 사용됩니다.
const multer = require('multer');
const upload = multer({
storage: multer.diskStorage({
destination(req, file, done) {
done(null, "uploads/");
},
filename(req, file, done) {
const ext = path.extname(file.originalname);
done(null, path.basename(file.originalname, ext) + Date.now() + ext);
},
}),
limits: { fileSize: 5 * 1024 * 1024 },
});
app.post("/upload", upload.single("image"), (req, res) => {
console.log(req.file);
res.send("ok");
});
multer 함수의 인수로 설정을 넣는다. storage 속성에는 destination(어디에), filename(어떤 이름으로) 저장될때의 옵션 값을 설정한다. file 객체에는 업로드한 파일에 대한 정보가 들어있다. done 매개변수는 함수이다. 첫 번째 인수에는 에러가 있다면 에러를 넣고, 두 번째 인수에는 실제 경로나 파일 이름을 넣어준다. req나 file의 데이터를 가공해서 done으로 넘기는 형식이다. limits 속성에는 업로드에 대한 제한사항을 설정할 수 있다.
- .single(fieldname): fieldname 인자에 명시된 이름의 단수 파일을 전달받는다. 이 파일은 req.file 에 저장된다. 이미지 하나는 req.file로 나머지 정보는 req.body에 저장된다.
- .array(fieldname[, maxCount]): fieldname 인자에 명시된 이름의 파일 전부를 배열 형태로 전달 받습니다. 이미지들은 req.files로 나머지 정보는 req.body에 저장된다.
- .fields(fields): fields 인자에 명시된 여러 파일을 전달 받는다. 파일 객체는 배열 형태로 req.files 에 저장된다. 이미지들은 req.file로 나머지 정보는 req.body에 저장된다.
- .none(): 오직 텍스트 필드만 허용합니다. 만일 파일이 업로드 되었을 경우, "LIMIT_UNEXPECTED_FILE" 와 같은 에러 코드가 발생합니다. 이는 upload.fields([]) 와 같은 동작을 한다. 모든 정보를 req.body에 저장된다.
Reference
[NodeJS]Express.js로 웹 서버 만들기 - 01
'백엔드 > Node.js' 카테고리의 다른 글
[Node.js] MySQL 연동 (1) | 2024.11.08 |
---|