Node_미들웨어

심동근·2024년 4월 2일

멋쟁이 사자처럼

목록 보기
13/19

미들웨어

  • 요청과 응답 중간에 있으면서 요청을 처리하거나 원하는 형태로 응답을 수정하는 기능을 가진 함수

라우트 미들웨어

  • 라우터 객체를 통해 라우트 코드를 정리하여 관리하기 쉽게 만들어주는(읽기 쉽게) 미들웨어
  • 같은 요청 URL을 사용한다면 묶은 후 mothod 방식만 구분하는 형태
  • 아래 코드에서 주석된 부분이 router를 사용하기 전(훨씬 보기 편해진 것을 확인할 수 있다.)
const express= require("express");
const app= express();

const router= express.Router();

app.get("/", (req, res)=>{ // 요청 방식을 함수 이름으로 사용 가능
    res.send("Hello, Node!");
})


router.route("/contacts")  
    .get((req, res)=>{
        res.send("Contacts page");
    })  
    .post((req, res)=>{
        res.send("Create Contact");
    });

// // 연락처 가져오기
// app.get("/contacts", (req, res)=>{
//     res.send("Contacts page");
// })

// // 새 연락처 추가하기
// app.post("/contacts", (req, res)=>{
//     res.send("Create Contact");
// })

router.route("/contacts/:id")
    .get((req, res)=>{
        res.send(`View Contact for ID : ${req.params.id}`)
    })
    .put((req, res)=>{
        res.send(`Update Contact for ID : ${req.params.id}`)
    })
    .delete((req, res)=>{
        res.send(`Delete Contact for ID : ${req.params.id}`)
    })

// // 연락처 1개 가져오기
// app.get("/contacts/:id", (req, res)=>{
//     res.send(`View Contact for ID : ${req.params.id}`)
// })

// // 연락처 수정하기
// app.put("/contacts/:id", (req, res)=>{
//     res.send(`Update Contact for ID : ${req.params.id}`)
// })

// // 연락처 삭제하기
// app.delete("/contacts/:id", (req, res)=>{
//     res.send(`Delete Contact for ID : ${req.params.id}`)
// })

app.use(router); 

app.listen(3000, ()=>{
    console.log("서버 실행 중");
})
  • 위의 작성한 라우트 코드는 라우트 미들웨어를 사용한 것이므로 어플리케이션에게 미들웨어를 사용했다는 것을 알려야 한다. 그때 사용하는 함수가 app.use라는 함수이다.

  • 일반적으로 라우터코드는 모듈로 저장한 후에 사용한다.

문제 발생

  • 라우터코드를 모듈로 저장한 후 저장했더니 아래와 같은 에러가 발생했다.
[nodemon] restarting due to changes...
[nodemon] starting `node app.js`
C:\mybox\repository\visual studio code\node\doit-node-main\doit-node-main\myContacts\node_modules\express\lib\router\index.js:469
      throw new TypeError('Router.use() requires a middleware function but got a ' + gettype(fn))
      ^

TypeError: Router.use() requires a middleware function but got a Object
    at Function.use (C:\mybox\repository\visual studio code\node\doit-node-main\doit-node-main\myContacts\node_modules\express\lib\router\index.js:469:13)
    at Function.<anonymous> (C:\mybox\repository\visual studio code\node\doit-node-main\doit-node-main\myContacts\node_modules\express\lib\application.js:227:21)
    at Array.forEach (<anonymous>)
    at Function.use (C:\mybox\repository\visual studio code\node\doit-node-main\doit-node-main\myContacts\node_modules\express\lib\application.js:224:7)
    at Object.<anonymous> (C:\mybox\repository\visual studio code\node\doit-node-main\doit-node-main\myContacts\app.js:10:5)   
    at Module._compile (node:internal/modules/cjs/loader:1369:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1427:10)
    at Module.load (node:internal/modules/cjs/loader:1206:32)
    at Module._load (node:internal/modules/cjs/loader:1022:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:135:12)

Node.js v20.12.0
[nodemon] app crashed - waiting for file changes before starting...

터미널을 전부 종료하고 vscode도 종료를 하려다가 그 전에 원인을 한 번 찾아보기로 하고 contactRouts.js 파일을 확인했는데

const express= require("express");
const router= express.Router();

router.route("/contacts")  
    .get((req, res)=>{
        res.send("Contacts page");
    })  
    .post((req, res)=>{
        res.send("Create Contact");
    });

router.route("/contacts/:id")
    .get((req, res)=>{
        res.send(`View Contact for ID : ${req.params.id}`)
    })
    .put((req, res)=>{
        res.send(`Update Contact for ID : ${req.params.id}`)
    })
    .delete((req, res)=>{
        res.send(`Delete Contact for ID : ${req.params.id}`)
    })

    module.exports= router;

문제 해결

오타는 없어보였다. 그때 마지막 줄 module.exports= router;이 들여쓰기가 되어있는걸 보게되서 뒤로 밀었는데 정상적으로 서버가 다시 실행되었다. 도저히 이해를 할 수가 없다. 예전에 spring 개발할 때 pom.xml에 직접 dependency를 추가했는데 계속 오류가 발생하다가 아무것도 없는 공백 줄 하나를 지웠더니 문제가 해결되었던 것과 같이 이해할 수 없는 일이 또 일어나고야 말았다.
아무튼 다시 module.exports= router;를 들여쓰기를 해도 오류는 발생하지 않게 되었다. 억울하다.

바디파서 미들웨어

  • 서버로 요청을 보낼 때 요청 본문에 담긴 것을 파싱하는 미들웨어
  • 파싱: 요청할 때 전송한 자료를 프로그램에서 사용할 수 있는 형식으로 변환하는 것
  • 요청 본문에 있는 내용을 프로그래밍에 사용할 수 있도록 파싱하려면 바디파서라는 미들웨어를 꼭 등록을 해야한다.
  • 바디파서 미들웨어를 등록하면 요청 본문을 가지고 와서 필요한 변수로 할당한 다음 프로그램 코드에 활용 가능하다.
// app.js
const express= require("express");
const app= express();

app.get("/", (req, res)=>{ // 요청 방식을 함수 이름으로 사용 가능
    res.send("Hello, Node!");
})

app.use(express.json());
app.use(express.urlencoded({extended : true}));

app.use("/", require("./routes/contactRoutes"));

app.listen(3000, ()=>{
    console.log("서버 실행 중");
})

코드 설명(app.js)

  • app.use(express.json());
    Express 애플리케이션에서 JSON 형식의 요청 바디를 파싱할 수 있도록 해준다. 클라이언트에서 보내는 HTTP POST 요청의 본문이 JSON 형식인 경우, 이 코드가 JSON 데이터를 JavaScript 객체로 파싱한다.

  • app.use(express.urlencoded({extended : true}));
    Express 애플리케이션에서 URL-encoded 형식의 요청 바디를 파싱할 수 있도록 해준다. URL-encoded 형식은 HTML 폼에서 보내는 기본적인 데이터 형식이다. {extended: true} 옵션은 내장된 queryString 라이브러리를 사용하여 복잡한 객체가 인코딩되는 것을 허용합니다.

따라서, 위의 코드는 Express 애플리케이션에서 JSON 데이터와 URL-encoded 데이터를 파싱하여 JavaScript 객체로 변환하고, 이러한 데이터를 사용하여 서버 측 로직을 처리할 수 있도록 도와준다.

-- contactRoutes.js
const express= require("express");
const router= express.Router();

router.route("/contacts")  
    .get((req, res)=>{
        res.send("Contacts page");
    })  
    .post((req, res)=>{
        console.log(req.body);
        const {name, email, phone}= req.body; // 구조 분해 할당 문법
        if(!name || !email || !phone){
            return res.send("필수값이 입력되지 않았습니다.");
        }
        res.send("Create Contact");
    });

router.route("/contacts/:id")
    .get((req, res)=>{
        res.send(`View Contact for ID : ${req.params.id}`)
    })
    .put((req, res)=>{
        res.send(`Update Contact for ID : ${req.params.id}`)
    })
    .delete((req, res)=>{
        res.send(`Delete Contact for ID : ${req.params.id}`)
    })

module.exports= router;

0개의 댓글