프로그래밍

express 라우트 미들웨어 질문

다음 두 개 코드의 결과가 왜 달라지는지 이유와 제게 이해가 부족한 개념을 알고 싶습니다.

 

GPT에 물어보니 대답을 정확하게 못하길래,, 개드립 고수님들께 질문드립니다.

 

// Common code for exam

 

const express = require('express')

const app = express()

const router = express.Router()

 

function fn (req, res, next) {

    console.log('I come here')

    next('router')

 }

 

// Here : define route and mount rounter instance to app

 

app.listen(3000,(req,res) => console.log("Go!"));

 

 

 

// case 1) first mount router instance 

/* result log

I come here
 I come here too

*/

 

app.use('/',router); //(1)

 

router.get('/foo', fn, (req, res, next) => {

    console.log('I dont come here1')

})

router.get('/foo', (req, res, next) => {

    console.log('I dont come here2')

})

 

app.get('/foo', (req, res) => {

    console.log(' I come here too')

    res.end('good')

})

 

// case 2) late mount router instance 

/* result log
 I come here too

*/

 

router.get('/foo', fn, (req, res, next) => {

    console.log('I dont come here1')

})

router.get('/foo', (req, res, next) => {

    console.log('I dont come here2')

})

 

app.get('/foo', (req, res) => {

    console.log(' I come here too')

    res.end('good')

})

 

app.use('/',router); //(2)

 

 

case1과 case2의 로그 출력 결과가 다른 이유를 이해하지 못하겠습니다.

왜 두번째 코드에서만 "I come here"가 미출력되는지 이해가 되지 않습니다.

 

두번째 코드에서 router 인스턴스가 동작을 안하는 것으로 보이네요.

 

 Q.제가 생각하는 가정은 다음과 같은데, 제가 잘못 이해한 부분이 있을까요? 

제가 express의 미들웨어 실행 등록 순서가 어떻게 정해지는지를 모릅니다...

- '/foo' 경로에 대한 app의 라우트가 먼저 등록된 후 router의 마운트가 나중에 실행됨. 

- '/foo' 경로에 대한 라우트 핸들러 실행 순서는 app 내장 라우트에 등록된 다음 함수가 제일 처음임

(req, res) => {

    console.log(' I come here too')

    res.end('good')

}

- 제일 처음 실행된 함수에 의해 request-response 사이클이 종료되어 router 인스턴스의 핸들러는 스킵됨.

 

 

이 문제와 관련해서 제가 학습이 필요한 자바스크립트, node js, 익스프레스 등의 개념이 있다면 말씀부탁드립니다. 

express 공식문서 보면서 개념 익히고 있는데, 부족한 부분을 인지하고 채울 수 있는 곳을 찾고자 합니다.

 

14개의 댓글

2024.02.05

간단한 호이스팅문제로 보이는데 확인해보세요. js는 호이스팅을 잘해줘야함미다

0
2024.02.05
@동탄올리버

제가 이해가 어려워서 그러는데

어느 객체가 호이스팅 문제가 있는지 간략한 설명 부탁드려요..

app.use()함수 호출 순서 차이와 호이스팅 개념을 연결 짓는게 힘들어서요.

0
2024.02.05
@아임니더

호이스팅: https://developer.mozilla.org/ko/docs/Glossary/Hoisting

 

middleware location: https://stackoverflow.com/questions/66968831/does-it-matter-where-i-place-app-usehelmet-within-the-app-use-statements

 

제가 질문을 제대로 안읽고 답변을 했네여 ㅈㅅㅈㅅ

 

미들웨어는 request 가 발생했을때 가장 상위에서 제일 먼저 반응합니다. express doc에 보면 가정하신부분이 맞을겁니다. 마운트시에 app.use보다 app.get이 먼저 반응해서 res.end로 끝내버리니 연결 종료된걸로 보이네요. doc에서도 app use를 상위로 올리라고 되어있지않나여? 본지오래되서 기억이안나네

0
2024.02.05
@동탄올리버

답변 및 링크 감사합니다.

 

다음 사이트 route 연습코드에서는 app.use()를 나중에 사용해서, 크게 상관없는줄 알고 있었네요.

https://expressjs.com/en/guide/using-middleware.html#middleware.application:~:text=)%0A%7D)-,Router%2Dlevel%20middleware,-Router%2Dlevel%20middleware

0
2024.02.06
@아임니더

반대로 말했네요 ㅋㅋㅋ 아래로내려야

0
2024.02.06
@동탄올리버

app.use()를 app.get()보다 상위에 올려야한다고 이해했습니다.

 

router객체를 app에 마운트하는 것이 app.use()에 역할인데, router 객체가 마운트되기 전에 app.get()에 의해 route가 등록되어 문제가 된것으로 보입니다.

 

하기 doc 링크에서 코드 순서대로 미들웨어함수의 순서가 정해진다는 사실을 알수 있었습니다.

https://expressjs.com/en/5x/api.html#router.param:~:text=Serve%20static%20files%20from%20multiple%20directories%2C%20but%20give%20precedence%20to%20%E2%80%9C./public%E2%80%9D%20over%20the%20others%3A

0
2024.02.07
@아임니더

https://stackoverflow.com/questions/20366765/express-js-app-usefunction-understanding-issue

 

app.use 는 app router 뒤로 쓰라고하네요

0
2024.02.07
@동탄올리버

찾아봐주셔서 감사합니다.

다만, 남겨주신 링크는 위 문제와 관련이 적은듯 하고, 제가 이해한 해결방식과 다른 듯합니다.

약 10년전 게시물이라 현재 express 버전과 차이가 있을 듯합니다.

질문자 코드에서도 router메소드를 사용하는 맥락이 제가 사용한 맥락과 다르네요.

저는 router()메소드를 클래스 함수로 사용하여, router 객체를 만들었습니다.

 

제가 이해한 해결방식은 app.use(path,router)를 app.get()보다 먼저 써야한다는 것입니다.

그래야 router 인스턴스에 등록된 route가 app 자체 route보다 먼저 실행될 수 있습니다.

 

middleware 실행 순서

(case1) router에 등록된 route -> app.get

(case2) app.get -> router에 등록된 route

 

0
2024.02.07
@아임니더

음 미들웨어는 무조건 라우트 전에 실행되어야 할텐데요. 예를들어, 제가 권한없는 상태에서 /upload 에 접근하려한다면 미들웨어에서 쳐내야 하잖아요?

 

express에서 middleware 는 app.use의 callback 함수로 등록을하는걸로 봐서는 route 객체하고는 별개인거 같아요.

 

위의 예시코드로는 res.end가 문제되는거 같습니다. connection 상태만 유지해준다면 위치는 상관없어보이는데요. res.end를 바꿔도 그런가요?

 

요기 참고해도 좋을거같아요

https://github.com/mazipan/nodejs-simple-restfull-with-express/tree/master

0
2024.02.08
@동탄올리버

app.get에 등록된 callback 함수도 미들웨어 스택에 저장된다고 저는 이해했습니다.

그래서, app.use('/',router)와 app.get('/foo',..) 코드 순서가 callback 함수의 실행 순서를 결정하는 것으로 이해했습니다.

 

case2에서 app.get()함수 로직을 res.end() 대신 next()를 사용하여 다음 미들웨어로 흐름을 넘겼습니다.

그 결과, router.get에 등록한 fn함수가 실행되는 것을 확인했습니다.

/*case2 결과*/

I come here too

I come here

 

case2 실행 순서 : '/foo' 경로 request > app.get > router.get

 

express에서 middleware 실행 순서는 middleware stack에 담겨진 순서대로 실행되는 것으로 알고있습니다.

next()를 사용하여 stack에 담긴 다음 middleware로 흐름을 넘겨주는 것으로 알고있습니다.

출처 - https://expressjs.com/en/guide/writing-middleware.html

 

남겨주신 rep의 app.js 코드 감사합니다.

확인한 결과, case2 코드같이 app.get과 router 객체를 같이쓸 때, path를 다르게 해서 쓰는게 났다고 생각되네요.

동일한 path에 대해서는 [callback ...] 같이 복수의 콜백을 router.get()등에 사용하는게 훨씬 보기 좋네요.

app.js에서는

1. app.use()로 복수의 미들웨어(logger 등)을 '/' 에 마운트. 즉, 모든 요청 발생시 처리됨.

2. app.use()로 복수의 router 객체를 각각 다른 path에 마운트 하였습니다.

3. 에러 핸들러 '/' 에 마운트.

 

실행 순서 : path 경로 request > loger > bodyParser.json() > ... > path에 따른 route

 

제가 잘못이해한 부분이 있다면 말씀부탁드립니다.

0
2024.02.05

express 오래 한 사람으로서 댓글 막 길게 썼다지웠다 했는데

그냥 한마디만 하고 감

이렇게 코딩하지 마셈. 제발.

0
2024.02.05
@zrGgwK0rad

배우는입장인데 물어볼수도 있죠 너무 빡빡하시네

2
2024.02.05
@동탄올리버

애초에 route path로 요청을 받았을때 무슨 http method가 걸리는지, 어떤 middleware를 거치는지, 결과는 어떻게나오는지를 최대한 간단하게 표현하는게 먼저임

비상식적인 결과를 의도한 js코딩은 jsfuck에 지나지않음

0
2024.02.05
@zrGgwK0rad

답변 감사합니다.

하기 연습코드 실습 도중, 코드에 app.use()가 명시되어 있지 않아서 2가지 케이스로 실습을 했었는데요.

어떤 결과가 정확하게 정상적인 결과인지 아직 초보라 알 수 없어서 여기에 질문남겼었습니다.

https://expressjs.com/en/5x/api.html#router.all:~:text=The%20following%20example%20illustrates%20next(%27router%27)%20usage.

 

말씀하신 뉘앙스로 보니, 1번 케이스가 정상적인 결과로 생각되지만, 지양해야할 코딩으로 생각되네요.

토이 프로젝트시, 요청에 대한 응답 프로세스가 명확하도록 작성해보겠습니다.

0
무분별한 사용은 차단될 수 있습니다.
번호 제목 글쓴이 추천 수 날짜 조회 수
5689 [프로그래밍] 엥 구글 플러터 유기각 재는거임?? 4 최수연 0 1 일 전 242
5688 [프로그래밍] 반도체 장비 업계인 있음? 9 캡틴띠모 0 2 일 전 227
5687 [프로그래밍] 안드로이드 책 추천좀 6 집에가게해줘 0 3 일 전 138
5686 [프로그래밍] 폰 스크리닝 해 본 사람 있어? 3 무지개빛푸딩 0 3 일 전 361
5685 [프로그래밍] jsp 트리메뉴 만들고있는데 구상한게가능한지 의견좀물어볼께 11 평택국 0 4 일 전 145
5684 [프로그래밍] JPA 도와줘어억 ㅠ 10 모그리또 0 4 일 전 227
5683 [프로그래밍] 의사는 뽑는 인원 제한하는데 부캠은 왜 제한 안 할까 5 조강현 0 6 일 전 353
5682 [프로그래밍] 그 혹시 게임쪽 종사자 있음? 17 god79ii 0 10 일 전 617
5681 [프로그래밍] 코린이 ㅅㅂ 뭐가 문젠지 모르겠어요 9 집에가게해줘 0 10 일 전 436
5680 [프로그래밍] Dear Imgui 라고 아시나요? 2 년째모쏠 0 10 일 전 241
5679 [프로그래밍] 현업개발자분들 주말엔 편하게 쉴수있나요? 10 키로 0 11 일 전 847
5678 [프로그래밍] 무엇이든 물어보세요. 28 변현제 0 13 일 전 405
5677 [프로그래밍] 개발자보단 엔지니어가 취업이 잘됨 5 iillillill 2 14 일 전 718
5676 [프로그래밍] 프론트엔드 개발자 연봉 1억 넘는 사람 있어? 13 잠적자 0 14 일 전 623
5675 [프로그래밍] Exiftool 이거 일본어 못 읽는데 13 부터시작하는이세... 0 16 일 전 233
5674 [프로그래밍] 반응형 웹페이지가 내가상상한거랑 좀 다르네 4 평택국 0 17 일 전 445
5673 [프로그래밍] 고졸 FE개발자 연봉, 상황에 조언좀.. 19 쾅꿍꿍 0 17 일 전 598
5672 [프로그래밍] 물경력들 보면 책임을 이해못하는것같음 5 mils 1 18 일 전 409
5671 [프로그래밍] GPT가 코딩 다해주네 3 겜신병자 0 18 일 전 741
5670 [프로그래밍] 크로스플랫폼의 욕심은 끝이없다 4 ye 0 21 일 전 399