-
express - Middleware(미들웨어)1FrameWork/Express.js 2023. 2. 15. 11:42
Middleware
미들웨어(middleware)는 그 이름에서 알 수 있듯이 중간단계 역할을 하는 존재이다.
express의 middleware를 사용해서 요청과 응답사이에 express 자체에 있는 기능외에 추가적인 기능을 넣어줄 수 있다. express 자체 미들웨어를 사용해도 되고 다른 사람이 만들어 놓은 미들웨어를 npm을 통해 다운 받아 사용해도 된다.
express 사용법에서 핵심은 '미들웨어'에 있다고 할 정도로 미들웨어는 express에서 중요한 역할을 한다. 미들웨어에는 인증 수행, 예외처리,세션처리,라우터 등 많은 종류가 있다.
app.use( )
미들웨어는 app.use() 메서드를 통해 사용한다. app.set( )과의 차이점은 app.set( )은 전역으로 사용된다는 점이다.
const express = require("express"); const app = express(); app.set("port", process.env.PORT || 8070); app.get("/", (req, res) => { res.send("Hello world"); }); const myLogger = (req, res) => { console.log("LOGGED"); }; app.use(myLogger); app.listen(app.get("port"), () => { console.log(app.get("port"), "번 포트에서 서버 실행중"); });
위 코드는 서버가 요청을 받을 때마다 'LOGGED'라는 메시지를 콘솔에 출력하게 한다. myLogger라는 미들웨어를 마들어 주었고 app.use()를 사용해서 미들웨어를 붙여주었기 때문이다.
그렇게 되면 요청(request)이 들어 올 때 마다 myLogger를 반드시 거치게 된다. 여기서 요청은 '/' 주소를 get 했을때, 즉 localhost:8070/에 접속했을 때를 말한다.
next( )
const express = require("express"); const app = express(); app.set("port", process.env.PORT || 8070); app.get("/", (req, res, next) => { res.send("Hello world"); next(); }); const myLogger = (req, res, next) => { console.log("LOGGED"); next(); }; app.use(myLogger); app.listen(app.get("port"), () => { console.log(app.get("port"), "번 포트에서 서버 실행중"); });
next()는 다음 미들웨어로 넘어가는 역할을 하기 때문에 순서를 잘 배치해 주고 next()를 통해 흐름을 잘 제어해주어야 한다. next()는 다음 미들웨어로 가는 역할을 하지만 몇가지 인자를 넣어 다른 기능을 하게 할 수도 있다.
next()의 종류 및 내용
종류 내용 next() 음 미들웨어로 가는 역할을 한다. next(error) 오류 처리 미들웨어로 가는 역할을한다. next('route') 많이 사용하지 않지만 next( )로 같은 라우터에서 분기처리를 할 때 사용한다. 오류 처리를 위한 미들웨어 함수
const express = require("express"); const app = express(); app.set("port", process.env.PORT || 8070); app.use(function (err, req, res, next) { console.error(err.stack); res.status(500).send("Someting broke!"); }); app.listen(app.get("port"), () => { console.log(app.get("port"), "번 포트에서 서버 실행중"); });
오류 처리를 위한 미들웨어 함수는 총 네 개의 파라미터 err,req,res,next를 가진다. 오류는 오류 처리 미들웨어에서 따로 다루어야 한다.
자주 사용하는 미들웨어
express.static
서버에서 응답할때 html 파일만 필요한 것이 아니라 보통 favicon,image,file,css등 다양한 종류의 파일이 필요하다.
예를 들어 이미지 파일을 html내에 띄우고 싶어서 html 파일에 이미지를 삽입하면 어떻게 될까?
=> 실제 브라우저에서는 이미지가 보이지 않게 된다. 이유는 html 파일은 이미지 파일이 어떤 것인지 모르기 때문이다.
image가 위치한 경로를 모두 써준다고 해도 Node.js자체를 서버에 올리기 때문에 서버에 맞게 설정을 해주어야 한다. 따라서 css,js등 *static 파일은 static끼리 모아 따로 폴더를 지정해 놓응 것이 좋다.
*static : 이미지,css,스크립트 파일과 같이 그 내용이 고정되어 있어, 응답을 할 때 별도의 처리 없이 내용 그대로를 보여주면 되는 파일을 의미한다.
const express = require("express"); const app = express(); app.set("port", process.env.PORT || 8070); // 기존의 http 모듈을 상속 받았기 때문에 http 모듈의 모든 기능을 사용할 수 있다. app.use(express.static(__dirname + "/public")); app.get("/", (req, res) => { res.sendFile(__dirname + "/index2.html"); }); app.listen(app.get("port"), () => { console.log(app.get("port"), "번 포트에서 서버 실행중"); });
static 메서드는 express안에 기본적으로 포함되어 있기 때눔에 별도의 설치 없이 꺼내서 사용해 주기만 하면된다. express.static()안에 static 폴더로 지정해줄 파일의 경로를 입력한다. 포기에서는 public이라는 폴더를 사용해서 static폴더로 지정해 주었다.
Index2.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>express로 웹페이지 만들기</title> </head> <body> <h2>express로 웹 만들기</h2> <p>메인 페이지입니다</p> <img src="./nodejs.png" /> </body> </html>
static 폴더를 따로 지정해주면 지정한 피일이 바로 클라이언트로 가는 것이 아닌 static미들웨어를 거치 후 도착하게 된다. 이렇게 지정했으면 이제 부터 static파일들을 불러 html에 띄울 수 있다.
그러면 위와 같이 html 파일 내에 public/ 이라는 경로를 따로 명시해주지 않아도 자동으로 서버에서 static폴더에서 해당 파일을 찾은 후 띄어 주게 된다. 경로를 모두 노출하지 않으므로 보안에도 도움이 된다.
router
router도 일종의 미들웨이이며, 클라이언트로 부터 요청(request)이 왔을 때 서버에서 어떤 응답(response)을 보내 주어야 할지 결정한다.
express에서 router는 'app.get', 'app.post','app.use'등 처럼 express 모듈을 담은 변수뒤에 http 메서드가 붙은 것인데, 이를 이용해 요청이 들어오는 경로와 응답을 만들 수 있다.
첫 번째 파라미터로 넣어준 경로로 요청이 들어오면 두 번째 파라미터의 미들웨어를 실행한다. 두번째 파라미터는 라우팅 로직 함수를 콜백형태로 구현한 것이고 해당 주소의 요청을 받으면 해당 미들웨어가 어떤 작업을 수행하게 된다.
app.get('/user/:id',function(req,res){ res.send("user id: "+ req.params.id); });
위와 같은 코드가 존재할 때 GET메서드로 /user/1이라는 URI 요청이 드러오면 이에 대한 응답으로 req.param.id에 접근하여 얻은 고객의 아이디를 문자열로 보내게 된다.
응답을 위한 함수
종류 내용 res.send( ) 문자열로 응답한다. res.json( ) json 객체로 응답한다. res.render( ) Jade,Pug와 같은 템플릿을 렌더링하여 응답한다. res.sendFile( ) 파일로 응답한다. app.get, app.use는 요청을 위한 함수이다.
morgan
morgan은 Logger API이다. morgan은 request와 response를 깔끔하게 포매팅해주어 콘솔에 로그를 찍는 역할을 한다. 호출된 router가 어떤 상태이고, 어떤 결과 값인지 보여준다. 그리고 이렇게 찍힌 로그를 콘솔로만 확인해도 되지만 json 형태로 dump 파일에 기록하게 해주는 winston이라는 모듈도 있다.
const logger = require("morgan"); app.use(logger("combined")); // ::1 - - [15/Feb/2023:02:36:25 +0000] // "GET / HTTP/1.1" 200 404 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) // AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36" app.use(logger("dev")); // GET / 200 5.470 ms - 404 app.use(logger("short")); // ::1 - GET / HTTP/1.1 200 404 - 4.986 ms app.use(logger("tiny")); // GET / 200 404 - 5.269 ms
morgan에는 인자로 여러 옵셔을 넣어줄 수 있고 옵션마다 보여주는 정보도 다르다. 주로 개발시에는 'dev'옵션을 사용한다. 요청 메서드, url, 상태, 응답시간 등을 보여주고 배포 시에는 'combined'옵션을 사용해 사용자의 주소, 브라우저 등 더 세부적인 정보를 로깅할 수 있다.
'FrameWork > Express.js' 카테고리의 다른 글
ExpressJS - express.js 활용1(next활용법, 자주 쓰는 미들웨어) (0) 2024.03.19 ExpressJS - express.js 서버 시작하기(setting, 미들웨어) (0) 2024.03.18 Express 미들웨어에 중요한 특징 (0) 2022.08.04 Express 서버 만들기 Application (0) 2022.08.03 Express 개요 (0) 2022.08.03