express.js
프레임워크를 사용하자마자 무턱대고 달아보는 미들웨어가 있다. express.json()
과 express.urlencoded()
이다. 둘의 역할이 무엇인지 제대로 짚고 넘어가기 위해 정리해봤다.
express.json()
는 POST
메소드를 사용하고 JSON형식의 payload가 있는 request
가 전해졌을 때, body를 파싱하는 미들웨어다.
사실 더 자세한 사용법을 알고자 했던 사유가 바로 이 미들웨어 때문이었다.
클라이언트 측에서 Fetch
를 이용하여 Request
의 body
에 평문을 보내게 했다. 다음과 같은 코드이다.
let body = "abcdefg";
fetch("localhost:5000/", {
method : POST,
headers : {
'content-Type' : 'application/json'
},
body : JSON.stringfy(body),
}).then(res=> console.log(res));
서버 측에서 어떻게든 이 값을 받아야했다. 기본적 express.js
예제로 간단하게 받으려고 했던 것이 문제가 생겼다. 문제가 된 코드는 다음과 같다.
const express = require("express");
const app = express();
const cors = express("cors");
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({extended:false}));
app.post("/", (req, res)=>{
str = req.body;
str = str.toUpperCase();
res.send(str);
})
app.listen(5000)
이때의 오류는 express.json()
에서 일으킨다. 무엇이 문제일까? 서버에서 request
로 받은 메시지가 문제였다. 사실상 문제라고 할 수는 없다. 다음의 사진처럼 request
메시지에 값은 잘 넘어가고 있기 때문이다.
진짜 문제는 express.json()
의 기본적인 설정으로 엄격한 JSON 규칙을 적용하고 있다는 것이다. 따라서 []
나 {}
같은 객체 형식으로 래핑이 되어있어야 한다. 지금과 같은 경우는 문자열만 넘어와서 문제가 되었다.
당장에 해결할 수 있는 방법은 함수 안에 JSON의 strict
설정을 false
로 지정해주는 것이다.
app.use(epxress.json({ strict:false }));
이제는 틀림없이 잘 작동할 것이다.
그렇다면 이제 express.json()
에서 쓸 수 있는 설정을 정리해보겠다.
inflate(default = true) : 압축형 body를 이용 가능하게 할 것인가(true), 아닌가(false)
limit(default = 100kb) : body의 데이터 크기의 상한선
reviver(default = null) : 이 부분은 추후에 추가하도록 하겠다.
strict(default = true) : 배열과 객체로 들어오는 값들만 처리할 것인지(true) 아닌지(false)
type(default = application/json) : 어떤 타입을 이 미들웨어에서 파싱이 될지 정하는 설정. 함수가 들어올 수도 있는데, fn(req)
의 형식으로 호출한다. 반환값이 truly 하면 파싱된다.
verify(default = undefined) : 함수가 전달되어야 한다. 사용한다면 verify(req, res, buf, encoding)
형식으로 호출된다. buf
는 Buffer
를 의미하고, encoding
은 request
의 변환 버전을 의미한다. 함수 내에서 에러를 발생시키면 파싱을 하지 않게 만든다.
인코딩 된 request
의 payload를 파싱해주는 미들웨어다.
cf. urlencode 란
URL에 맨 끝에 Query가 작성되는 것을 심심치 않게 봤을 것이다. 예를 들면 다음고 같은 형식이다.
fruit=APPLE&animal=DOG&people=ALICE
Request
메시지에 body에도 이런 형식으로 payload가 작성되어 보내질 수 있다. 보통 과거의 form에 입력되어 보내지는 값들이 이렇게 담겨 보내졌다.
fn(req)
의 형식으로 호출한다. 반환값이 truly 하면 파싱된다.verify(req, res, buf, encoding)
형식으로 호출된다. buf
는 Buffer
를 의미하고, encoding
은 request
의 변환 버전을 의미한다. 함수 내에서 에러를 발생시키면 파싱을 하지 않게 만든다.결론적으로는 client가 보내는 Request
메시지의 payload가 어떤 형식으로 작성되는 지에 따라 사용하는 미들웨어가 다르다고 할 수 있다.
물론 미들웨어의 설정을 변경하면 달라질 수 있지만, 일반적으로 content-type
이 application/json
이면 express.json()
, application/x-www-form-urlencoded
이면 express.urlencoded()
로 payload가 파싱된다고 생각하면 되겠다.