프로젝트 TIL (5) - [ XML -> JSON 변환, CORS 이슈 ]
오늘 한 일 🥴
오늘은 네이버 도서 API에서 카테고리별로 도서 정보를 받아오는 기능을 구현했습니다.
이 API는 사용자가 요청한 카테고리별로 도서를 필터링하여 응답해주는 API인데 클라이언트에서 요청하려고 하니 CORS 에러가 났습니다.
해결하기 위해 요청 시 headers에 Access-Control-Allow-Origin 설정도 추가해보고 이런저런 방법을 적용해보았지만 해결되지 않아서 검색한 결과 이 API는 서버프로그래밍(python, jsp, php, node.js 등)을 통해서 호출하도록 되어 있었습니다.
그 이유는 다른 사람의 클라이언트 id, secret을 도용해서 API를 호출하는 것을 막기 위해서입니다.
그래서 저는 서버에서 처리하기 위해 다음과 같은 과정을 거쳐 해결하였습니다.
- 카테고리별로 서버에 요청이 들어올 라우팅 설정 (매개변수로 카테고리 번호 넘기기)
- 요청으로 넘어온 카테고리 번호를 사용하여 서버에서 네이버 API 요청
- 네이버 API에서 응답으로 온 XML 데이터 -> JSON 데이터로 변환 (xml2js 모듈 사용)
- 변환한 데이터를 클라이언트에 응답으로 보내줌
이 API는 반환 값이 XML이기 때문에 xml2js 모듈을 사용하여 JSON 데이터로 변환을 해주어야 했습니다.
router.post("/", (req, res) => {
const { select } = req.body;
axios.get(`https://openapi.naver.com/v1/search/book_adv.xml?d_publ=${encodeURI(
"교보문고")}&d_catg=${select}&display=4`,
{
headers: {
"X-Naver-Client-Id": "클라이언트 id",
"X-Naver-Client-Secret": "클라이언트 secret",
},
}
)
.then((data) => {
let resultSendData = null;
xml2js.parseString(data.data, (err, result) => {
if (err) {
throw err;
}
const json = JSON.stringify(result, null, 4);
resultSendData = json;
});
return resultSendData;
})
.then((data) => res.status(200).send(data));
});
req.body로 들어온 select(카테고리 번호) 값을 추출 후, axios를 사용하여 API 요청을 합니다.
이 때, encodeURL을 사용하여 출판사 정보를 UTF-8로 인코딩해주어야 합니다.
headers에 발급받은 클라이언트 id와 secret 키를 넣어서 요청 후, then으로 받아온 xml 데이터를 xml2js.parseString을 통해 json 데이터로 변환시켜 클라이언트에 응답으로 보내줍니다.
( JSON.stringify() 메서드의 3번째 인자로 넣은 값은 json으로 변환한 데이터의 가독성을 높이기 위해 공백을 조정할 수 있는 옵션으로 유용하게 사용하였습니다. )
마치며
클라이언트가 아닌 서버에서 처리해야하는 것인지 몰라서 한참 해매기도 했지만 덕분에 xml데이터를 json 데이터로 변환하는 방법을 경험해볼 수 있어서 좋은 기회가 되었습니다.
이 API 말고도 REST API 요청을 할 때에는 CORS 이슈가 자주 발생하게 되는데 매일 마주하는 에러가 아니었다보니 CORS에 관하여 블로깅을 했음에도 불구하고 관련 지식이 내 머릿속에서 증발해버렸습니다..............
이번 기회에 블로깅한 내용을 다시 정독하고 구글링하여 개념을 좀 더 명확하게 짚고 넘어갈 수 있게 되었습니다!
✌️😜