[Node.js] 서버생성
▶ 익스프레스 프로젝트 시작하기
▷ Express 소개
-
http 모듈로 웹 서버를 만들 때, 코드가 보기 좋지 않고 확장성도 떨어진다.(4장 노드서버만들기)
-
npm에는 위와같은 불편을 해소하고 편의 기능을 추가한 웹 서버 프레임워크가 있다.
-
대표적인 것이 Express
▶ package.json 만들기
-
먼저 npm init 명령어 생성
-
모듈설치
npm i express
npm i -D nodemon
- nodemon은 개발용으로만 사용할 것을 권장
▷ express 서버 만들기
- 서버의 역할을 할 app.js를 다음과 같이 적는다
const express = require("express"); // 서버생성
// express란 http 확장판
const app = express();
app.set("port", process.env.PORT || 3000);
app.get("/", (req, res) => {
res.send("Hello, Express");
});
app.listen(app.get("port"), () => {
console.log(app.get("port"), "번 포트에서 대기 중");
});
- 익스프레스에서는
res.write
나res.end
대신res.send
를 사용하면 된다. - GET 요청 외에도 POST, PUT, PATCH, DELETE, OPTIONS에 대한 라우터를 위한 app.post, app.put, app.patch. app.delete, app.options 메서드가 존재한다.
서버 구동에 핵심이 되는 파일
-
app.set(“port”, 포트번호) 로 서버가 실행될 포트 지정 (포트 번호가 없을 때 기본값: 3000포트)
-
app.get(“주소”, 라우터) 로 GET 요청이 올 때 어떤 동작을 할지 지정
- 라우터: 담당자의 개념(이거 내가 담당해야하는 것 맞아? 내가 뭘 해줘야해?)
- app.listen(“포트번호”, 콜백)으로 몇 번 포트에서 서버를 실행할지 지정
▷ express 서버 실행하기
npm start
를 콘솔(터미널)에서 실행
▷ HTML로 응답하기
HTML로 응답하기 위해 res.sendFile 메서드를 사용해야한다. 단,파일의 경로를 path 모듈을 사용해서 지정해야 한다.
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"), "번 포트에서 대기 중");
});
▶ 미들웨어
- 미들웨어는 익스프레스의 핵심이다.
- 요청과 응답의 중간(middle)에 위치하기 때문에 미들웨어(middleware)라고 부른다.
- 미들웨어는 요청과 응답을 조작해 기능을 추가하기도 하고, 나쁜 요청을 걸러낸다.
- 미들웨어 사용법:
app.use(미들웨어)
로 장착 - 미들웨어는 req, res, next가 매개변수인 함수이다. (req: 요청, res: 응답, next(): 다음 미들웨어로 넘어감)
const express = require("express");
const path = require("path");
const app = express();
app.set("port", process.env.PORT || 3000);
app.use((req, res, next) => {
console.log("모든 요청에 다 실행됩니다.");
next();
});
app.get(
"/",
(req, res, next) => {
console.log("GET / 요청에서만 실행됩니다.");
next();
},
(req, res) => {
throw new Error("에러는 에러 처리 미들웨어로 갑니다.");
}
);
app.use((err, req, res, next) => {
console.error(err);
res.status(500).send(err.message);
});
app.listen(app.get("port"), () => {
console.log(app.get("port"), "번 포트에서 대기 중");
});
/
는 주소를 나타내며req, res, next
는 라우터를 뜻한다.- ★
next();
를 불러줘야 다음 미들웨어로 넘어간다.
- 미들웨어는 인자가 없어도 실행이 된다.
- 주소를 첫 번째 인수로 넣어주지 않는다면 미들웨어는 모든 요청에서 실행되고, 주소를 넣는다면 해당하는 요청에서만 실행된다
- app.use나 app.get 같은 라우터에 미들웨어를 여러 개 장착할 수 있다.
- 현재 app.get 라우터에 미들웨어가 두 개 연결되어 있다.
▷ 에러처리 미들웨어
-
현재 app.get(‘/’)의 두 번째 미들웨어에서 에러가 발생하고, 이 에러는 그 아래에 있는 에러 처리 미들웨어에 전달된다.
- 에러 처리 미들웨어는 매개변수가
err, req, res, next
로 네 개이다. (모든 매개변수를 사용하지 않더라도 매개변수가 반드시 네 개여야 한다.) - 첫 번째 매개변수는 반드시 error가 위치해야한다.
- res.status 메서드로 HTTP 상태 코드 지정 가능하다(기본값200)
- 특별한 경우가 아니면 가장 아래에 위치하도록 한다.
▽ 자주 쓰는 미들웨어
morgan
,cookie-parser
,express-session
설치- app.use로 장착
- 내부에서 알아서 next를 호출해서 다음 미들웨어로 넘어간다.
터미널에 다음과 같이 입력
npm i morgan cookie-parser express-session dotenv
(dotenv를 제외한 다른 패키지는 미들웨어이다. dotenv 패키지는 .env 파일을 읽어서 process.env로 만든다.)
app.js
const express = require("express");
const morgan = require("morgan");
const cookieParser = require("cookie-parser");
const session = require("express-session");
const dotenv = require("dotenv");
const path = require("path");
dotenv.config(); // process.env로 만듬
const app = express();
app.set("port", process.env.PORT || 3000);
app.use(morgan("dev"));
app.use("/", express.static(path.join(__dirname, "public"))); // static(설명아래)
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser(process.env.COOKIE_SECRET));
app.use(
session({
resave: false,
saveUninitialized: false,
secret: process.env.COOKIE_SECRET,
cookie: {
httpOnly: true,
secure: false,
},
name: "session-cookie",
})
);
app.use((req, res, next) => {
console.log("모든 요청에 다 실행됩니다.");
next();
});
app.listen(app.get("port"), () => {
console.log(app.get("port"), "번 포트에서 대기 중");
});
.env
COOKIE_SECRET = cookiesecret;
▷ dotenv
.env파일을 읽어서 process.env로 만든다.
- process.env.COOKIE_SECRET에 cookiesecret 값(키=값 형식)이 할당된다.
- ★즉, env 같은 별도의 파일에 비밀 키를 모아두고 dotenv 패키지로 비밀 키를 로딩하는 방식으로 관리하는 것이다.(.env 파일만 잘 관리하면 됨)
▷ morgan
- 서버로 들어온 요청과 응답을 기록해주는 미들웨어
-
로그의 자세한 정도 선택 가능: dev,tiny,short,common,combined (개발 환경에서는 dev를, 배포 환경에서는 combined 주로 이용)
- 아래와 같이 사용한다.
app.use(morgan("dev"));
▷ static
- 정적인 파일들을 제공하는 미들웨어
- 파일이 있을 때 fs.readFile로 직접 읽을 필요가 없다.
- static 미들웨어는 정적인 파일들을 제공하는 라우터 역할을 한다.
- 요청하는 파일이 없으면 알아서 next를 호출해 다음 미들웨어로 넘어가며, 파일을 발견했다면 다음 미들웨어는 실행하지 않는다.
- 아래와 같이 사용한다.
app.use("요청 경로", express.static("실제 경로"));
예시(위에 나와있는 코드)
- public이라는 안에 파일을 위치 시켜주면 ㅍ클라이언트가 계속 접속할 수 있다.
app.use("/", express.static(path.join(__dirname, "public")));
▷ body-parser
- 요청의 본문에 있는 데이터를 해석해서 req.body 객체로 만들어주는 미들웨어이다.
- 보통 폼 데이터나 AJAX 요청의 데이터를 처리한다.
- 아래와 같이 사용한다.
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
- JSON은 JSON 형식의 데이터 전달 방식이고, URL-encoded는 주소 형식으로 데이터를 보내는 방식이다.
-
json 미들웨어는 요청 본문이 json인 경우 해석, urlencoded 미들웨어는 폼 요청 해석
- urlencoded 메서드를 보면
{ extended: false }
라는 옵션이 들어있는데, ★이 옵션이 false이면 노드의 querystring 모듈을 사용해 쿼리스트링을 해석하고, true이면 qs 모듈을 사용해 쿼리스트링을 해석한다.
버퍼 데이터나 text 데이터일 때는 body-parser를 직접 설치해줘야 함
npm i body-parser
const bodyParser = require("body-parser");
app.use(express.raw());
app.use(express.text());
▷ cookie-parser
요청 헤더의 쿠키를 해석해주는 미들웨어
//나중에작성하기
댓글남기기