코딩쌀롱

2021.3.17(wed)_express의 use, get 본문

회고/하루 기록

2021.3.17(wed)_express의 use, get

이브✱ 2021. 3. 18. 15:36

문제 발생 코드 

익스프레스 서버 app.js

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

// 생략..

const indexRouter = require('./routes/index.js')
const itemsRouter = require('./routes/item-list.js')
app.get('/', indexRouter)
app.get('/item-list', itemsRouter)

//생략..

 

 itemsRouter 라우터 객체를 exports하는 routes/item-list.js

const express = require('express');
const router = express.Router();
const items = require('../data/homeContents.json');

router.get('/', (req, res) => {
    const i = req.query.index;
    const item = items.contents[i].eventContent;
    res.send(item);
});

module.exports = router;

 

fetch 요청을 하는 클라이언트 js의 fetch 부분

// this.URL = 'http://localhost:3000'
// idx = 0
fetch(`${this.URL}/item-list?index=${idx}`)
   .then(res => res.json())
   .then(this.renderItems.bind(this))

 

문제 살펴보기 

위 코드를 요약하면 다음과 같다.

1. 클라이언트에서 fetch 요청  → fetch('http://localhost:3000/item-list?index=0)
2. app.js에서 app.get('/item-list', itemsRouter) 
3. item-list.js에서
 router.get('/', ~~) 

 

이렇게 했을 때 다음의 에러가 발생한다.

에러를 들어가 살펴보면, 서버에서 json 파일을 보낸 것이 아니라 에러를 보여주는 html을 보내서 발생한 에러같다.

 

 문제 해결 ① 

문제를 해결하기 위해 계속 찾아보다가 router.get의 메소드를 use로 바꿔주니 해결이 됐다.

1. 클라이언트에서 fetch 요청  → fetch('http://localhost:3000/item-list?index=0)
2. app.js에서 app.get('/item-list', itemsRouter)
3. item-list.js에서 router.use('/', ~~) 

get에서 use로 메소드만 변경했다. 처음에 든 생각은 'router는 express의 하위버전으로 get, use가 같이 동작하는데 fetch로 get요청을 했는데 왜 못 받지?'였다.

 

use 메서드는 모든 HTTP 메서드에 대해 요청 주소만 일치하면 실행되지만
get, post, put, patch, delete 같은 메서드는 주소뿐만 아니라 HTTP 메서드까지 일치하는 요청일 때만 실행된다.
- 출처(backback.tistory.com/341)

use 메서드는 주소만 일치한다면 실행, get은 http 요청이 일치해야 실행. 이걸 보고 다음과 같은 생각을 했다.

 

1. 클라이언트에서 fetch로 '/item-list' get요청을 하고,

2. app.js에서 app.get('/item-list, itemsRouter)로 get 요청을 받아 item-list.js로 연결해줬고,

3. item-list.js에서 router.get('/', ~~) 이 코드를 만나게 된다. 그런데 이 코드는 fetch의 get요청을 직접 받은 게 아니기 때문에 http의 get요청을 받지 못하는 것 아닐까?! use로 했을 때 해결이 됐던 이유는 use는 http 메서드와 상관없이 주소만 일치하면 실행되기 때문에 use로는 실행이 됐던 것이고..

 

그렇다면 반대로는? 해봤다.

 

 문제 해결 ② ‣ 이게 더 맞는 방법인 듯..

express 서버에서 app.use / routes에서 router.get으로 바꿔봤다.

1. 클라이언트에서 fetch 요청  → fetch('http://localhost:3000/item-list?index=0)
2. app.js에서 app.use('/item-list', itemsRouter)
3. item-list.js에서 router.get('/', ~~) 

1. 클라이언트에서 fetch로 '/item-list' get요청을 하고,

2. app.js에서 app.use('/item-list, itemsRouter)로 주소가 일치해서 itemsRouter로 연결

3. item-list.js에서 router.get('/', ~~) 이 코드가 get 요청을 받아줌. 

 

express가 상위레벨, router가 하위레벨이라는 걸 생각하고 제이슨의 한 말씀을 읽어보자.

a, b, c 라우터가 있을 때, 
app.js라는 상위 레벨에서 get, post, put, delete 등을 구분하면 코드의 흐름이 이상해지니까..
app.js에서는 해당 경로로 오는 요청을 use로 각각의 하위 라우터에 위임하고,
하위 라우터가 get, post 등으로 메소드별로 처리하는 구조가 맞지 않을까. 
   - 제이슨의 한 말씀

맞는 것 같다! 그래서 현재 이 코드로 수정했다.

 

마무리

별 거 아닌 것 같은 이것 때문에....하루를 보냈다. 경우를 테스트해보다가 헷갈리고 정리 안 하고 넘어가기엔 너무 찝찝해서...ㅠㅠ 그래도 조금은 express에 한 발짝 다가간 느낌인데 아오 한 게 없어서 또 화나네 -.-

 

테스트해보면서 느낀 점을 기억하기 위해 적자면,

get은 http get 요청만받기 때문에 get, get 연달아서 안 되는 것 같다. 그리고 app.js 상위 레벨에서 경로에 따라 use로 라우터에 위임하고 라우터에서 get 메서드로 처리하는 게 맞는 것 같다. 

 

혼자 테스트해보고 제이슨과 대화하면서 쓴 글이기 때문에 맞지 않는 내용일 수 있습니다ㅠㅠ

혹시 더 선명하게 알고 계시다면!! 댓글로 알려주시면 절하겠습니다🙇🏻‍♀️

 

 

'회고 > 하루 기록' 카테고리의 다른 글

2021.4.21(wed)_OAuth  (2) 2021.04.21
2021.4.13(tue)_React  (0) 2021.04.13
2021.3.4(thu)_pipe 화살표함수로  (0) 2021.03.04
2021.3.3(wed)_TIL(ES Modules, 배열에 비동기, slice, substring)  (0) 2021.03.04
Comments