[Web Server] 기초 | Express

Eunji Lee·2022년 12월 9일
0

[TIL] Front-end

목록 보기
22/36
post-thumbnail

Express란

  • Express: Node.js 환경에서 웹 서버, 또는 API 서버를 제작하기 위해 사용되는 프레임워크
  • Express에서 구현한 서버가 Node.js HTTP 모듈로 작성한 서버와 다른 점
    • 미들웨어를 추가할 수 있음
    • 라우터를 제공함

참고사항
MERN stack: JavaScript 생태계에서 인기 있는 프레임워크인 MongoDB, Express, React, Node.js를 지칭




Express 시작하기

express 설치하기

터미널에서 해당 코드를 작성하면 express가 설치됨

npm install express

간단한 서버 만들기

  1. 초기 세팅하기
    (1) express 모듈을 가져오고 express라는 변수에 저장하기
    (2) express 애플리케이션 만들기
    (3) port 지정하기
  2. 경로 정의하기
    (1) app.get(): 경로('/')에 HTTP GET 요청이 있을 때마다 호출되는 콜백 함수
    (2) 콜백 함수는 reques와 response 객체를 인수로 사용
    ⚠️ 아래 예제에서는 단순히 응답에 대해 send()를 호출하여 문자열 "Hello World!"를 반환함
  3. 서버를 해당 포트에 시작하기
    (1) 콘솔 로그에는 'Example app listening on port 3000' 이 출력됨
//1.
const express = require('express') // (1)
const app = express() //(2)
const port = 3000 //(3)

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

//3.
app.listen(port, () => {
	console.log(`Example app listening on port ${port}`)
}) //(1)



Express 응용하기

라우팅하기

  • 라우팅: 메서드와 url에 따라 분기(Routing)하기
    • 클라이언트는 특정한 HTTP 요청 메서드(GET, POST 등)와 함께 서버의 특정 URI(또는 경로)로 HTTP 요청을 보냄
    • 라우팅을 통해 클라이언트의 요청에 해당하는 Endpoint에 따라 서버가 응답하는 방법을 결정함
  • 라우트 모듈을 메인 애플리케이션(서버가 있는 코드)과 분리해서 관리하는 것이 코드 유지, 보수에 유리함

예시

  • 서버가 있는 코드
const express = require('express')
const app = express()
const port = 3000

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

// 새로 추가된 코드
const wiki = require('./wiki.js')
app.use('/wiki', wiki) //wiki.js의 경로에 모두 '/wiki'가 있는 것으로 간주

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})
  • 라우트 모듈
// wiki.js - Wiki route module

const express = require('express')
const router = express.Router()

// Home page route
router.get('/', (req, res) => { // '/wiki' 와 동일한 의미
  res.send('HomePage');
})

// About page route
router.get('/about', (req, res) => { // '/wiki/about'과 동일한 의미
  res.send('AboutPage');
})

module.exports = router

미들웨어

  • 미들웨어(Middleware): 프로세스 중간에 관여하여 특정 역할을 수행하기
    • 요청(Request)에 필요한 기능을 더하기
    • 문제가 발견된 요청을 걷어내기

활용 예시

POST 요청 등에 포함된 body(payload)를 구조화할 때

  • Node.js HTTP 모듈의 경우: 네트워크 상의 chunk를 합치고, buffer를 문자열로 변환함
let body = [];
request.on('data', (chunk) => {
  body.push(chunk);
}).on('end', () => {
  body = Buffer.concat(body).toString();
  // body 변수에는 문자열 형태로 payload가 담겨져 있습니다.
});
  • express의 경우
const jsonParser = express.json();

// 생략
app.post('/api/users', jsonParser, function (req, res) {

})
  • express.json() 사용 중에 오류가 발생시 options에 {strict: false} 추가하기
const jsonParser = express.json({strict: false});
// 생략
app.post('/api/users', jsonParser, function (req, res) {

})

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

  • Node.js HTTP 모듈의 경우
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()
}
  • express의 경우: cors 미들웨어 사용하기
npm install cors //터미널에 입력하기
  • 모든 요청에 대해 CORS 허용하는 경우
const cors = require('cors');
// 생략
app.use(cors());
  • 특정 요청에 대해 CORS 허용하는 경우
const cors = require('cors')
 // 생략
app.get('/products/:id', cors(), function (req, res, next) {
	res.json({msg: 'This is CORS-enabled for a Single Route'})
})

모든 요청에 대해 url이나 메서드를 확인할 때

ex. 미들웨어 로거(logger): 디버깅이나, 서버 관리에 도움이 되기 위해 console.log로 적절한 데이터나 정보를 출력함

  • 데이터가 여러 미들웨어를 거치는 동안 응답할 결과를 만들어야 한다면, 미들웨어 사이사이에 로거를 삽입하여 현재 데이터를 확인하거나, 디버깅에 사용

  • endpoint가 /이면서, 클라이언트로부터 GET요청을 받았을 때 적용되는 미들웨어

  • 파라미터의 순서에 유의

    • req : 요청(request)
    • res: 응답(response)
    • next : 다음 미들웨어를 실행

  • use 메서드로 모든 요청에 대하여 미들웨어를 적용하기

const express = require('express');
const app = express();

const myLogger = function (req, res, next) {
  console.log('LOGGED');
  next();
};

app.use(myLogger);

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

app.listen(3000);
  • 모든 요청에 대해 메서드와 url을 출력하는 예시
const express = require('express');
const app = express();

const myLogger = function (req, res, next) {
  //req를 활용합니다.
  next();
};

app.use(myLogger);

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

app.listen(3000);

요청 헤더에 사용자 인증 정보가 담겨있는지 확인할 때

ex. HTTP 요청에서 토큰이 있는지를 판단하여, 이미 로그인한 사용자일 경우 성공, 아닐 경우 에러를 보내는 경우

  • cf. 토큰(Token): 주로 사용자 인증에 사용
app.use((req, res, next) => {
  // 토큰이 있는지 확인, 없으면 받아줄 수 없음.
  if(req.headers.token){
    req.isLoggedIn = true;
    next();
  } else {
    res.status(400).send('invalid user')
  }
})

0개의 댓글