티스토리 뷰

JavaScript/JS백엔드

[Express] 미들웨어

염두리안 2025. 1. 13. 20:53
728x90
반응형

미들웨어? Express에서 리퀘스트와 리스폰스 사이에 위치하여 어떤 작업을 실행하는 함수

 

미들웨어 구조

  • 파라미터가 2개인 경우(가장 기본적인 구조) : req, res
  • 3개인 경우 : req, res, next
    • next : 다음 미들웨어로 넘어가는 파라미터(다음 미들웨어를 가리킴)
  • 4개인 경우 : err, req, res, next
  • 참조문서: https://expressjs.com/ko/api.html#req
 

Express 4.x - API 참조

Access the API reference for Express.js detailing all modules, methods, and properties for building web applications with this version.

expressjs.com

// 파라미터가 3개인 경우
function meeting(req, res, next) {
  console.log('오!');
  next();
}

function greeting(req, res, next) {
  console.log('안녕!');
  res.json({ message: '연결 성공!' });
}
// 아규먼트 전달 순서에 따라 미들웨어 순서 결정
app.get('/hello', meeting, greeting);

 

미들웨어 사용법

  • all 매소드 : 특정한 app 객체의 매소드가 아닌, 모든 http 매소드의 대한 리퀘스트를 미들웨어로 전달
function greeting(req, res, next) {
  return res.json({ message: '연결 성공!' });
}
app.all('/hello', greeting);

app.all('/hello', (req, res, next) => {
  console.log('안녕 all!');
  next();
})
app.get('/hello', (req, res, next) => {
  console.log('안녕 get!');
  return res.json({ message: '연결 성공!' });
});
// GET http://localhost:3000/hello 를 하면 all과 get이 둘다 실행되는 이유?
// 두 함수 경로가 '/hello'라서 두 개 다 실행됨

  • use 매소드 : http 매소드와 관계 없이 모든 리퀘스트가 지정한 미들웨어를 거쳐가게 할 수 있음
    • 만약, 첫번째 파라미터인 경로를 생략하면 항상 실행됨
app.use('/hello', (req, res, next) => {
  console.log('안녕 use!');
  next();
})
app.all('/hello/all', (req, res, next) => {
  console.log('안녕 all!');
  next();
})

// 위 코드를 GET http://localhost:3000/hello/all 로 접속하게 되면
// `/hello` 경로를 거쳐 `/hello/all`로 도달

 

미들웨어로 req, res 다루기

  • 리스폰스와 리퀘스트 객체는 객체이기 때문에 원하는 값 추가 가능
function authentication(req, res, next) {
  req.user = 'Admin';
  next();
}
app.get('/me', authentication, (req, res, next) => {
  console.log(req.user);
  res.json({ user: req.user });
});

// GET http://localhost:3000/me 로 접속하면

이렇게 뜹니다

 

에러 처리하기

  • Express에선 모든 것이 미들웨어이기 때문에, 에러 처리할 때도 미들웨어를 사용함
  • errorHandler의 경우, throw키워드를 발생시키거나 next() 아규먼트를 넘겨줬을 때 실행됨
  • 에러 핸들러를 정의하지 않았는데 에러가 처리되는 이유? Express 내장 기능 때문(HTML로 정의됨)
    • Express로 웹API를 만들고 있다면, 리스폰스로 HTML이 아닌, JSON으로 전달해야 함 => 에러 핸들러의 경우, 다른 라우터보다 아래에 작성해야 함
// throw
function error(req, res, next) {
  throw new Error('에러 발생!');
  next();
}

// next
function error(req, res, next) {
  next(new Error('에러 발생!'));
  next();
}

throw, next 둘 다 동일 에러 발생

// 에러 핸들러(JSON) - 에러 발생시 무조건 실행
// 특정 경로에만 적용하고 싶다면, 첫번째 아규먼트에 경로 추가
app.use((err, req, res, next) => {
  console.log(err);
  res.json({ message: '에러 핸들러!' });
})

HTML이 아닌 JSON으로 전달됨
콘솔로 에러 객체 내용도 확인 가능

 

내장 미들웨어

  • express.json() : 리퀘스트 바디 속성에 json 추가해서 데이터를 담음
    • 실행 결과로 함수 자체를 반환함
app.use(express.json());
app.post('/products', (req, res) => {
  console.log(req.body);
  res.json({ message: 'Product 추가하기' });
});

// app.http
POST http://localhost:3000/products
Content-Type: application/json

{
    "name": "상품 1",
    "price": 100
}

  • express.urlencoded() : 주로 html 입력폼을 통해 서버를 데이터로 전송할 떄 사용
    • 리퀘스트 콘텐트 타입 헤더가 application/x-www-form-urlencoded 일 경우, key-value로 된 리퀘스트 바디들과 리퀘스트 객체의 바디 속성에 객체로 지정하게 됨
    • extended의 값을true로 할 경우 보다 복잡한 키와 속성을, false로 할 경우 단순한 키와 값만 가져옴
    • 참고문서: https://expressjs.com/en/api.html#express.urlencoded
 

Express 4.x - API Reference

Access the API reference for Express.js detailing all modules, methods, and properties for building web applications with this version.

expressjs.com

app.use(express.urlencoded({ extended: true }));
app.post('/users', (req, res) => {
  console.log(req.body);
  res.json({ message: 'User 추가하기' });
})

  • express.static() : 서버의 파일을 서버 외부로 전송하기 위해 사용
// app.js
app.use(express.static('public'));

// http
GET http://localhost:3000/index.html

public 폴더 안에 있는 index.html 파일 접속 가능

 


서드파티 미들웨어

// app.js
app.get('/hello', (req, res) => {
  console.log(req.headers.cookie);
  return res.json({ message: '안녕, 쿠키 (;' });
});

// http
GET http://localhost:3000/hello
Cookie: taste=chocolate

문자열

npm install cookie-parser
import express from 'express';
import cookieParser from 'cookie-parser';

const app = express();

app.use(cookieParser());

app.get('/hello', (req, res) => {
  console.log(req.cookies);
  return res.json({ message: '안녕, 코드잇 (;' });
});

app.listen(3000, () => {
  console.log('Server is listening on port 3000');
});

객체로 내용 확인

npm install morgan
// 최소한의 정보를 남기는 옵션
import express from 'express';
import morgan from 'morgan';

const app = express();

app.use(morgan('tiny'));

app.get('/hello', (req, res) => {
  return res.json({ message: '안녕, morgan (;' });
});

app.listen(3000, () => {
  console.log('Server is listening on port 3000');
});

// http
GET http://localhost:3000/hello

  • cros : 웹사이트가 다른 도메인에 있는 리소스에 접근할 수 있도록 브라우저에서 HTTP 헤더를 통해 제어하는 것
npm install cors
import express from 'express';
import cors from 'cors';

const app = express();

app.use(cors());

app.get('/hello', (req, res) => {
  return res.json({ message: '안녕, cors (;' });
});

app.listen(3000, () => {
  console.log('Server is listening on port 3000');
});
  • multer : Content-Type이 multipart/form-data인 리퀘스트를 간편하게 다룰 수 있는 미들웨dj
    • multipart/form-data? 입력폼을 작성하고 전송할 때, 다양한 타입의 데이터를 전송 가능하게 하는 타입 | 이 타입으로 전달받은 데이터를 리퀘스트 객체에서 사용할 수 있도로 함
    • 공식문서: https://github.com/expressjs/multer
import express from 'express';
import multer from 'multer';

const app = express();

const upload = multer({ dest: 'uploads/' });

app.post('/profile', upload.single('avatar'), function (req, res, next) {
  // ...
});

app.listen(3000, () => {
  console.log('Server is listening on port 3000');
});
728x90
반응형

'JavaScript > JS백엔드' 카테고리의 다른 글

[Express] 파일 업로드  (0) 2025.01.14
[Express] 라우터  (1) 2025.01.14
물리적 모델링  (0) 2025.01.02
정규화  (0) 2025.01.02
논리적 모델링  (4) 2025.01.02
최근에 올라온 글
최근에 달린 댓글
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Total
Today
Yesterday
반응형