상세 컨텐츠

본문 제목

node.js를 공부해보자 (4 : express web server 만들기)

일기장/개발일기

by lofty statue 2021. 10. 8. 23:31

본문

 

이전 http에 대한 내용들을 배울 때 GET, POST, PUT, PATCH, DELETE 이 친구들에 대한 분기처리를 하는 코드를 작성했고 리팩토링까지 했다. 근데도 아직 많이 지저분한 감이 없지 않다. 그리고 나중에 쿠키, 세션 등을 작업하면 코드가 더욱 지저분해지고 서버 규모가 커질수록 더 개발하기가 힘들어진다. 이럴 때 express를 사용하면 기능들을 쉽고 간결하게 사용할 수 있다.

그리고 express만의 파일 구조가 있는데 npm i -g express-generator라는 명령어로 간편하게 만들 수 있다.

그리고 scripts 부분의 start를 써서 node로 실행할 수도 있지만 npm start로도 실행할 수 있다. 로직을 보면  bin/www가 서버 실행부고 핵심 로직은 app.js에 들어있다. 하지만 통째로 보면 복잡하니 조금씩 때어서 보자.

express를 통해서 호출하면 app 객체를 만들 수 있다. 그 app이라는 객체가 가장 핵심적인 역할을 한다고 생각하면 된다.  그냥 node서버에서는 res.end로 했는데 app에서는 res.send로 하고 있다. 이 부분은 express에서 res 객체에 send라는 기능을 추가해준 것이다. 이런 식으로 라우터를 간편하게 하나씩 추가해줄 수 있다.

여기서 app.get()은 GET 요청을 의미한다. post, delete 같은 메소드도 지원하니 같은 방식으로 라우터를 계속해서 만들 수 있다. 이런 것들을 하나씩 추가해서 라우터들을 app에다가 연결해준다.

하지만 원래 app.js를 보면 GET,POST 이런것보다는 set이나 use 같은 게 훨씬 더 많이 보인다. 이때 app.set은 express 설정이나 혹은 값을 저장하는 용도로 사용하고 app.use는 미들웨어를 장착하는데에 사용된다. 하나씩 보자면 우선 첫번째 set같은 경우는 views라는 폴더의 경로를 지정해주는 역할을 하고 있다. 두번째 set은 view engine으로 pug를 사용한다는 이야기이다. 즉 pug라는 것이 html을 대체하도록 설정한다는 이야기다. use안에 들어있는 친구들은 미들웨어(middleware)라고 한다. 이것이 express의 가장 핵심적인 기능이다. 그렇기에 위 코드처럼 단순하게 router만 붙인다고 해서 express서버를 돌리면 이 express서버가 어떻게 돌아가는지는 전혀 모르는거다. 그렇기에 미들웨어를 이해하는 것이 가장 핵심적이다.

그러면 이 미들웨어라는 것은 무엇일까?

기본적으로 우리가 아는 구조는 요청을 받고 응답을 하는 게 기본적인 서버의 요청응답 구조인데 미들웨어를 사용하면  요청이 왔을 때 app.js 내부에 있는 미들웨어들을 쭉 내려와서 마지막에 응답이 되서 클라이언트한테 보내진다. 그렇기에 app.use 안의 req, res로 요청과 응답을 조작할 수 있다. 그리고 세번째 매겨변수로 next라는 것을 추가해야 다음 미들웨어로 넘어가게 된다. 

즉, 요청(req) -> 미들웨어들(app.use) -> 응답(res)

이 위에서는 두번째 미들웨어에서 next를 안붙였기 때문에 그 이후의 라우터 요청이나 미들웨어로 넘어갈 수 없다. 그래서 화면을 가져오는 get같은 것들또한 되지 않기 때문에 제대로 서버에 접속되지 않는다. 물론 의도적으로 안붙여도 된다. 그런데 get이나 post같은 경우에는 미들웨어임에도 next를 안붙인다. 왜냐하면 app.get, app.post 등은 GET,POST 요청들에만 걸리는 미들웨어를 장착해서 주소가 붙으면 그 주소와 일치하는 요청에만 걸리게 된다. (특수한 미들웨어들)

(예를 들어 app.get('/users')는 이 주소로 요청을 보낼때만 동작하는 미들웨어가 된다.)

그렇기에 app.use는 모든 경우에 다 적용되는 미들웨어이고 app.get같은 라우팅 미들웨이일 경우에는 특수한 경우에만 걸리는 미들웨어다. 그 외에도 app.options라는 것도 CORS요청(너 내 요청 받아줄거야?)을 할 때 쓰는 특수한 미들웨어이다.  

???? 근데 왜 여기서는 use에 next 안붙어있는데 왜 넘어가지? 이 경우에는 내장된 함수에 다 next가 포함되어 있기 때문이다. (ex : logger) 아무튼 미들웨어의 흐름은 반드시 숙지해야 한다.

그리고 이런 식으로 미들웨어를 싹 다 한줄에 연결해서 쓸 수도 있다. 

ex: app.use(미들,미들,미들), app.get(미들,미들,미들)

보기에는 지저분하지만 쭉 연달아서 써도 순서대로 작동한다.

그리고 라우팅 미들웨어를 처리하는 또 다른 방법에 대해서 알아보자. 아까전에는 get,post 등의 라우팅 미들웨어들을 직접 작성해서 썼는데 왜 이렇게 사용을 할까? 만약 서버의 규모가 커진다면 app.js에 지나치게 많은 라우터들을 작성하게 될 것이다.

그렇기 때문에 이런 것을 방지하고자 다른 파일에 라우팅 미들웨어를 작성하고 모듈을 활용해서 불러온다.

그리고 라우터 파일에서는 app.get 대신 router.get 으로 사용한다. 이런 방식으로 app.js에서 라우터들을 분리할 수 있다.

그래서 indexRouter는 알겠는데 usersRouter는 뭔데? 그 위 사진을 보면은 이해할 수 있다. 즉, 이 경우의 indexRouter들은 /인 경우에 돌아가는 라우터들이고 app.use('/users')는 /users가 붙은 경우를 모두 통용해서 말하는 것이다. 그렇기에 usersRouter같은 경우에 요청을 쓸때는 앞에 '/users'를 일일히 붙일 필요가 없다. 즉, 공통적인 주소를 가진 경우들을 묶어서 처리할 수 있다.

그래도 만약 이 라우터에 하나도 안걸린다면(ex: 없는 주소가 들어왔을 때) 응답을 꼭 보내줘야 하는데 라우터에 일치하는 주소들이 없으면 (즉, next도 하지 않고 res메소드도 사용하지 않으면) 클라이언트는 timeout이 될때까지 계속 기다리게 된다. 이 때를 404 not found라고 하는데 이런 경우를 처리하는 미들웨어를 아래에 반드시 둬야 함. 

그 외의 에러 상황(ex : 500번대 에러, 사실 404도 처리해줌, 참고로 400번대는 client에서 에러가 발생한 거고 500번대는 서버에서 에러가 발생한 경우)은 http-error라는 패키지를 가져와서 사용해도 되긴 하지만 직접 짜보자. 이런 경우에는 에러가 뭔지 알아야 하니까 err라는 파라미터를 하나 더 추가해서 받아온다. 아 그리고 에러가 날만한 부분은 try/catch로 감싸줘야 서버가 고장이 안난다. 이렇게 되면 에러처리가 되는 모습을 확인할 수 있다.

 

유명한 미들웨어들(morgan, body-parser, cookie-parser, express-session, flash)

참고로 미들웨어들의 순서가 중요한 경우가 있으니 숙지아면 좋음

ex: passport같은 미들웨어를 쓸 때는 express-session이 먼저 등록이 되어있어야 한다.

morgan: 어떤 요천이 들어오고 어떤 응답을 했는지 알려줌

body-parser: req.on과 req.end 데이터를 해석해주는데 최신 버전부터는 자동으로 해석해줘서 사용할 필요 X

cookie-parser: 쿠키를 해석해주는 미들웨어. 쿠키가 클라이언트에 저장되는데 이 쿠키가 위조된 쿠키인지 아닌지를 확인하기 위해서는 'secret code' 옵션이 필요하다. secret code라면 올바른 코드로 인식을 함.(일종의 쿠키에 대한 비밀번호)

static: 정적 파일용 라우터 역할을 하며 파일을 못 찾으면 next(내장됨)를 한다. public폴더의 정적파일들을 가져와줌.

express-session: 메모리 세션을 활성화해주는 역할을 함. 옵션을 붙일 수 있는데 보통은 위의 코드처럼 씀. 그리고 secret은 쿠키 파서에도 똑같이 'secret code' 옵션을 넣어줘야 한다. saveUnitialized는 처음의 빈 세션객체라도 저장을 할지, resave는 세션 객체에 수정 사항이 없더라도 저장을 할지 정할 수 있다.

flash : 로그인 실패시 1회용 팝업메시지를 띄울 때 사용한다.

 

이 강의자료들은 osam.kr의 node.js 기본부터 프로젝트 실습까지(조현영님) 라는 강의를 토대로 작성하였습니다. 사실 제가 받아들인 대로 쓰는거라서 틀린 내용이 있을 수 있으니 혹시 사실과 다른 부분이 있으면 피드백 해주시면 감사하겠습니다.

관련글 더보기