[Server] node.js Express를 이용한 서버 구현

somin·2021년 8월 4일
1

server

목록 보기
5/13
post-custom-banner

Express로 서버 구현하기

Express로 구현한 서버와 http 모듈로 작성한 서버의 차이

  1. 미들웨어 추가가 편리
  2. 자체 라우터를 제공

1. MERN stack

  • JavaScript 생태계에서 인기 있는 프레임워크인 MongoDB, Express, React, Node를 지칭
  • Express.js : Node.js 환경에서 웹 서버, 또는 API 서버를 제작하기 위해 사용되는 프레임워크로 Node.js를 위한 빠르고 개방적인 간결한 웹 프레임워크

2. Express 설치

npm install express --save

: myapp 디렉토리에 Express를 설치한 후 종속 항목 목록에 저장

npm install express

: Express를 임시로 설치하고 종속 항목 목록에 추가하지 않으려면 --save 옵션을 생략

3. 웹 서버 만들기

const express = require('express')
const app = express()
const port = 5000
const ip = "localhost"

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

app.listen(port, () => {
  console.log(`http server listen on ${ip}:${port}`)
})
  • 앱은 서버를 시작하며 5000번 포트에서 연결
  • 앱은 루트 URL(/) 또는 라우트에 대한 요청에 “Hello World!”로 응답
  • 다른 모든 경로에 대해서는 404 Not Found로 응답

4. Middleware

  • 미들웨어 : 프로세스 중간에 관여하여 특정 역할을 수행
  • 미들웨어 이용시 node.js만으로 구현한 서버에서는 번거로울 수 있는 작업을 보다 쉽게 적용 가능
  • 미들웨어 작성시 req, res, next 필요
    *현재의 미들웨어 함수가 요청-응답 주기를 종료하지 않는 경우 next()를 호출하여 그 다음 미들웨어 함수에 제어를 전달해야 함

자주 사용하는 미들웨어

  1. 모든 요청에 대해 url이나 메소드를 확인할 때
  2. POST 요청 등에 포함된 body(payload)를 구조화할 때(쉽게 얻어내고자 할 때)
  3. 모든 요청/응답에 CORS 헤더를 붙여야 할 때
  4. 요청 헤더에 사용자 인증 정보가 담겨있는지 확인할 때

1) 모든 요청에 대해 url이나 메소드 확인

  • 로거(logger) : 디버깅이나, 서버 관리에 도움이 되기 위해 console.log로 적절한 데이터나 정보를 출력
const myLogger = function (req, res, next) {
  console.log(`http request method is ${req.method}, url is ${req.url}`)
  next()
  // next() : 그 다음 미들웨어 함수가 호출되며 없으면 다음 미들웨어로 넘어가지 않음
}

app.use(myLogger)

morgan 모듈을 사용하여 console.log 출력 가능

const morgan = require("morgan")
app.use(morgan("http request method is :method"))
// http request method is POST, http request url is /upper
app.use(morgan("dev"))
// POST /upper 201 19.535 ms - 4

2) POST 요청 등에 포함된 body(payload) 구조화

app.use(express.json({ strict: false }))
// string 등 원시타입 데이터도 json parsing 해주도록 설정

app.post("/upper", (req, res) => {
  res.status(201).json(req.body.toUpperCase())
  // 상태 코드 : 201
  // req.body에는 JSON의 형태로 payload가 담겨져 있는데, 여기에 toUpperCase()하여 json으로 응답으로 보냄
});
  • res.send() : send에 전해진 argument에 따라서 Content-type이 자동적으로 만들어짐
  • res.json() : json이 아닌 것도 json 형식으로 바꾸어서 보내줌
    *content-type 헤더를 application/JSON으로 고정
  • app.use(express.urlencoded({extended: ture})) : 객체 형태로 전달된 데이터내에서 또다른 중첩된 객체를 허용

3) CORS 미들웨어

(1) 순수한 node.js로 작성한 코드

const defaultCorsHeader = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
  'Access-Control-Allow-Headers': 'Content-Type, Accept',
  'Access-Control-Max-Age': 10
}

if (req.method === 'OPTIONS') {
  res.writeHead(201, defaultCorsHeader)
  res.end()
}

(2) Express 프레임워크를 활용해 작성한 코드

npm i cors

const cors = require('cors')

const corsOptions = {
  origin: "*",
  methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
  allowedHeaders: ["Content-Type", "Accept"],
  maxAge: 10,
}

app.use(cors(corsOptions))
// 정해진 cors 설정만 허용

app.use(cors())
// 모든 요청에 대해 CORS 허용

4) 요청 헤더의 사용자 인증 정보 확인

app.use((req, res, next) => {
  // 토큰이 없으면 받아줄 수 없음
  if(req.headers.token){
    req.isLoggedIn = true;
    next()
  } else {
    res.status(400).send('invalid user')
  }
})
  • HTTP 요청에서 토큰이 있는지 여부를 판단하여, 이미 로그인한 사용자일 경우 성공, 아닐 경우 에러를 보내는 미들웨어 예제

5. 라우팅: 메소드와 URL에 따라 분기(Routing)하기

  • 클라이언트는 특정한 HTTP 요청 메소드(GET, POST 등)나 서버의 특정 URI(또는 경로)로 HTTP 요청을 보냄
  • 라우팅은 클라이언트의 요청에 해당하는 메소드와 Endpoint에 따라 서버가 응답하는 방법을 결정
    *라우팅(Routing) : 메소드와 URL로 분기점을 만드는 것
  • 파일을 분리했을 때의 전략

1) 순수한 node.js로 작성한 코드

const requestHandler = (req, res) => {
  if(req.url === '/upper') {
    if (req.method === 'GET') {
      res.end(data)
    } else if (req.method === 'POST') {
      req.on('data', (req, res) => {
        // do something ...
      })
    }
  }
}

2) Express 프레임워크를 활용해 작성한 코드

// upper.js
const express = require("express")
const router = express.Router()

router.post("/", function (req, res) {
  res.status(201).json(req.body.toUpperCase())
})

module.exports = router
// express-server.js
const upper = require("./router/upper");
// upper.js의 경로 지정

app.use("/upper", upper);
// url이 /upper일 때

References

1. Express 공식 문서

profile
✏️
post-custom-banner

0개의 댓글