프로젝트 리뷰/Book-Square

프로젝트 TIL (5) - [ XML -> JSON 변환, CORS 이슈 ]

Lee_hyojin 2020. 9. 28. 01:09

오늘 한 일 🥴

 

오늘은 네이버 도서 API에서 카테고리별로 도서 정보를 받아오는 기능을 구현했습니다.

이 API는 사용자가 요청한 카테고리별로 도서를 필터링하여 응답해주는 API인데 클라이언트에서 요청하려고 하니 CORS 에러가 났습니다.

 

해결하기 위해 요청 시 headers에 Access-Control-Allow-Origin 설정도 추가해보고 이런저런 방법을 적용해보았지만 해결되지 않아서 검색한 결과 이 API는 서버프로그래밍(python, jsp, php, node.js 등)을 통해서 호출하도록 되어 있었습니다.

그 이유는 다른 사람의 클라이언트 id, secret을 도용해서 API를 호출하는 것을 막기 위해서입니다.

 

 

그래서 저는 서버에서 처리하기 위해 다음과 같은 과정을 거쳐 해결하였습니다.


 

  1. 카테고리별로 서버에 요청이 들어올 라우팅 설정 (매개변수로 카테고리 번호 넘기기)
  2. 요청으로 넘어온 카테고리 번호를 사용하여 서버에서 네이버 API 요청
  3. 네이버 API에서 응답으로 온 XML 데이터 -> JSON 데이터로 변환 (xml2js 모듈 사용)
  4. 변환한 데이터를 클라이언트에 응답으로 보내줌

 

이 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에 관하여 블로깅을 했음에도 불구하고 관련 지식이 내 머릿속에서 증발해버렸습니다..............

 

이번 기회에 블로깅한 내용을 다시 정독하고 구글링하여 개념을 좀 더 명확하게 짚고 넘어갈 수 있게 되었습니다!

✌️😜