Interaction With Server - Node.js, Express

Ben Lee·2021년 6월 27일
0

Node.js에서의 HTTP interaction

기본적인 Node.js를 사용하면 HTTP의 요청과 응답은 다음과 같은 contents를 포함하여 이루어진다.

HTTP 요청 (클라이언트 -> 서버)

메소드 -> req.method
URL -> req.url
헤더 -> req.headers
바디 -> chunk,buffer 사용

HTTP 응답 (서버 -> 클라이언트)

응답코드, 헤더 -> res.writeHead(200, '헤더정보')
바디 -> res.end('바디 내용')

Node.js로 바디를 주고 받는 과정을 Express라는 프레임워크를 사용하여 위의 과정을 간단하게 해결할 수 있다.

Express


JavaScript 생태계에서 인기 있는 프레임워크의 앞글자를 따서 MERN stack (MongoDB, Express, React, Node) 이라고 부른다. 이 중 Express.js는 Node.js 를 위한 빠르고 개방적인 간결한 웹 프레임워크 중 하나로, 라우팅/세션과리 등 골치아픈 부분을 해결하여 쉽게 웹 서버를 구축할 수 있게 도와준다.

Express의 설치와 안내는 공식 문서를 참조한다. 공식 문서 내부 상단 탭에서 시작하기와 안내서를 필히 탐독해야 한다. 아래의 코드는 express 설치가 완료된 것을 전제한 코드로 가장 간단하게 만들어본 서버이다.

const express = require('express')
const app = express()
const port = 3000

const allMessages = [];
//클라이언트에서 보내는 메시지를 담을 수 있는 배열
app.use(express.json());
//bodyparser 대신 바디를 받아올 수 있는 미들웨어

app.get('/messages', (req, res) => {
  res.status = 200;  
  res.json({
      results: allMessages
  });
  // 객체의 형태로 존재하는 results에 모든 메시지를 배열의 형태로 담는다.
  // res.send대신 Res.json({});으로 파싱 가능한 JSON 문자열을 받을 수 있다.
  // 이 때, res.send와 res.json을 사용할 경우 res.end는 생략 가능
}) 

app.post('/messages', (req, res) => {
    allMessages.push(req.body);
    //post시 req.body를 push한다.
    res.status(201); //성공시 반환
    res.end('post: Hello World!') //성공시 반환
  })

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

module.exports = app;

미들웨어(Middleware)란?

컨베이어 벨트 위에 올라가있는 request에 무언가 악세사리를 붙이거나, 불량품이라면 밖으로 걷어내는 역할을 한다고 한다. 미들웨어가 주로 쓰이는 상황은 다음과 같으며, Node.js만을 이용해서 구현할 때에 번거로운 작업을 미들웨어를 통해 손쉽게 해결할 수 있다.

1. 모든 요청에 대해 url이나 메소드를 알고자 할 때

가장 단순한 미들웨어는 logger 다. 말 그대로 로거는 디버깅이나, 서버 관리에 도움이 되기 위해 console.log를 적절하게 찍어주는 역할을 합다. 미들웨어는 다음 구성을 가진다.

app.use((req,res,next) => {
  console.log(`${req.url} ${req.method} 로그찍는 미들웨어`);
  // 로그 찍는 미들웨어
  next();
  // 컨베이어 벨트에서 검수가 끝나면 다음으로 보내주는 역할
})

2. POST 요청 등에서 쓰이는 body(payload)를 쉽게 얻어내고자 할 때

app.use(express.json());
// Express 코드 상단에 작성한다.
//바디를 받아올 때 미들웨어를 사용하여 bodyparser를 사용해야하나
//최신의 문법에는 이것이 이미 내장되어 있어 코드가 한결 간편해짐

//POST 요청과 같이 바디가 필요한 곳에 코드를 작성하면 된다. 
console.log(req.body)

3. 모든 요청/응답에 CORS 헤더를 붙일 때

앞서 순수 node.js 코드로 CORS 헤더를 붙이려면, 응답 객체의 writeHead 메소드 등을 이용해 일일이 Access-Control-Allow-* 헤더를 정의하고, OPTIONS 메소드에 대한 라우팅도 구현해줘야만 했다.

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()
}

CORS 미들웨어를 통해 코드가 간단해진다.

const cors = require('cors')

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

// 특정 요청에 대해 CORS 허용
app.get('/products/:id', cors(), function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for a Single Route'})
})

4. 요청 헤더에 사용자 인증 정보가 담겨있는지 확인하고 싶을 때

HTTP 요청에서 토큰(주로 사용자 인증에 쓰임)의 여부를 판단하여, 이미 로그인한 사용자일 경우 성공, 아닐 경우 에러를 보내는 미들웨어이다.

app.use((req, res, next) => {
  // 토큰 여부 확인
  if(req.headers.token){
    req.isLoggedIn = true;
    next()
  } else {
    res.status(400).send('invalid user')
  }
})

node.js 디버깅

$ node –inspect-brk server.js
profile
개발자가 되고픈 엔지니어

0개의 댓글