6. 익스프레스 웹서버 만들기

Donghun Seol·2022년 9월 22일
0

node.js 교과서

목록 보기
8/12

6. 익스프레스 웹서버 만들기

Cheat Sheet

npm install express-generator
req.cookies # 쿠키 객체
req.session # 세션 객체
req.body # POST 객체
req.params.<id|type|...etc> # routing params(:id)
req.query # query params(?query=myquery)
app.use(...middlewares)
app.use('/', customRouter) // usually router defined in anothor files
router.get('/', custromRouterMiddleware);
next('route') // 다음 '라우터로' 전달
next(error) // 다음 에러핸들러로 전달
res.status(200|403|404)
   .send
   .json
   .redirect
   .render
   .sendFile
   .end

6.1 익스프레스 프로젝트 시작하기

설치

npm i express
npm i -D nodemon

# or use express-generator
npm i express-generator
express <project title> --view=nunjucks

기본 메서드

// set value in app object
const express = require('express');
const app = express();

app.set('port', process.env.PORT || 3000);
app.get('/', (req, res, next) => {
  res.status(200).send('Hello Express');
});

app.listen(app.get('port'), () => {
  console.log('express server running on ', app.get('port'));
});

6.2 자주 사용하는 미들웨어

미들웨어

요청을 받아서, 미들웨어를 거치고, 그 결과를 응답으로 보내준다.
웹서버 동작의 핵심. app.use() 메서드로 미들웨어 활용한다.
app.use()로 등록된 콜백함수들은 모든 요청에 대해서 순차적으로 실행된다.
따라서 미들웨어의 호출 순서는 매우 중요하다.
미들웨어에서 내부적으로 next()를 호출하는 경우도 있지만, 커스텀 미들웨어 함수를 작성하는 경우 next()를 호출해주어 다음 미들웨어로 처리를 넘겨야 한다.
미들웨어의 첫번째 인수로 주소를 넣어주지 않으면 모든 주소에 대해서 해당 미들웨어가 실행된다.
에러 처리 미들웨어의 매개변수는 (err, req, res, next) 4개다.

app.use((req, res, next) => {
  console.log("이 로그는 요청이 올때마다 항상 실행됨");
  next();
});
app.get(/*some routing */);
app.post(/*some routing */);

// NOTE : error handling middleware's callback has 4 params
app.use((err, req, res, next) => {
  console.error(err);
  res.status(500).send(err.message);
});

morgan

로깅을 위한 미들웨어,

app.use(morgan('dev'|'combined'|'common'|'short'))

static

스태틱 파일을 제공하는 라우터 역할, 따로 설치는 필요없다.
쿠키, 세션과 조합하는 경우 호출하는 위치에 주의한다.

app.use('/', express.static(path.join(__dirname, 'public')));

body-parser

express에 포함되어 따로 설치할 필요 없다.(4.16버전부터)
post나 put요청에 포함되는 데이터를 파싱한다.

app.use(express.json());
app.use(express.urlencoded({extened:true}));

쿠키는 사용자가 보관하여 요청시마다 헤더에 포함해서 서버로 전송하는 정보
세션은 서버가 가지고 있다가 사용를 식별하는데, 보통 쿠키에 포함된 세션 id를 키로 세션정보를 추출한다.

cookie-parser로 해석된 쿠키들은 req.cookie 객체에 예쁘게 파싱되어 들어간다.
다만 쿠키를 지우거나 생성하려면 res.cookie(), res.clearCookie()를 활용해야 한다.

app.use(cookieParser([비밀키]));
app.use(session( {
  resave: false, // 세션에 변화가 없을시 다시 저장하는지 여부
  saveUninitialized: false,
  secret: process.env.COOKIE_SECRET, // 쿠키 서명에 필요한 비밀키
  cookie: {
    httpOnly:true, // 클라이언트에서 쿠키 활용 안됨
    secure: false, // 배포시에는 https 활용하고, true로 하는 것이 좋음
  },
  name: 'session-cookie',
}));

session.destroy() // 세션 삭제

미들웨어의 특성

아래와 같이 미들웨어를 연달아 장착 가능. 내부적으로 next() 호출하지 않으면, 명시해줘야 한다.

app.use(
	morgan('dev'),
	express.json(),
	cookieParser(process.env.COOKIE_SECRET),
);

next('route')는 다음 라우터로 요청객체를 넘긴다.
next('err')는 다음 에러처리 미들웨어로 요청을 넘긴다.

미들웨어 안에 미들웨어를 삽입하여 조건에 따라 미들웨어를 호출하게 코딩가능하다.
내부에 있는 미들웨어를 호출할때 (req, res, next)를 전달해줘야 함을 확인하자

app.use((req, res, next) => {
  if (process.env.NODE_ENV === 'production') {
    morgan('combined')(req, res, next);
  } else {
    morgan('dev')(req, res, next);
  }
});

multer

파일이나 이미지를 전송하는 multipart/form-data인 폼은 multer로 해석 가능하다.

<form action="/upload" method="post" enctype="multipart/form-data">
  <input type="file" name="image" />
  <input type="text" name="title" />
  <button type"submit">업로드</button>
</form>
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(</* input type=file의 name 속성값 */>),
		(req, res) => { console.log(req.file, req.body.title);
						res.send('ok');
		});

6.3 Router 객체로 라우팅 분리

6.4 req, res 살펴보기

CheatSheet 참고

6.5 템플릿 엔진 사용하기

pug

사용을 추천하지만 문법때문에 호불호가 갈린다.
코드양이 매우 줄지만, 인덴테이션을 엄격하게 지켜야 한다.
익숙하지 않으면 퍼그파일만 보고 html을 한눈에 파악하기 어렵다.
그래서 넌적스를 활용하기로 함.

nunjucks

mozilla에서 만든 html 문법과 유사한 템플릿 엔진
설치

npm i nunjucks
const nunjucks = require('nunjucks');
app.set('view engine', 'html');
nunjucks.configure('views', {
  express: app,
  watch: true,
});

res.render('index', {title:'title Variable'});
<p>welcome to {{title}}</p> // 변수
{% set innerVal = 'myVal' %} // 내부 변수

// 반복문
{% set fruits = ['apple', 'orange', 'pear'] %}
{% for item in fruits %}
<li>{{item}}</li>
{% endfor %}

// 조건문 {% elif %}도 사용 가능함.
{% if isLoggedIn %}
<div>로그인 완료!</div>
{% else %}
<div>로그인 해주세요</div>
{% endif %}

// include
{% include <filename> %}
  
// 레이아웃과 블록 이런 식으로 활용한다.
{% extends <경로> %} 
// 레이아웃을 불러와서 레이아웃의 block에 해당하는 부분을 아래 내용으로 교체해서 렌더링~

{% block content %}
<h1>{{title}}</h1>
{% endblock %}

res.render의 변수 주입법

res.render('index', {...data}); // 방법 1

res.locals.message = <message>; // 방법 2 res.locals 활용
res.locals.error = <error message>;
profile
I'm going from failure to failure without losing enthusiasm

0개의 댓글