axios와 fetch

이로그·2024년 5월 19일
0

React

목록 보기
1/2

리액트를 공부하던중, “공공데이터포털”의 오픈 API를 사용하여 나라별 정보를 불러와서 여행일기장을 만들어보고 싶단 생각이 들었다.

HTTP에 요청할 수 있는 도구는 axios와 fetch가 있는데, 우선 fetch로 작업을 해보았다.

✅공공데이터포털 오픈 API 정보

✅작업 코드(fetch)

const url = `http://apis.data.go.kr/1262000/CountryBasicService/getCountryBasicList?ServiceKey=${key}&numOfRows=1&pageNo=1`;

**fetch**(url).then((res) => {
    console.log(res);
});
  • XML 형태의 데이터가 올거라 예상했지만, 아래의 이미지와 같은 응답을 받아서 코드를 잘못 작성한건가 싶었다.
  • type: ‘cors’가 떠서 처음엔 cors 에러인줄 알았는데, status가 200이고, cors 에러가 뜨면 Response 객체가 아닌 에러메세지가 뜬다고 해서 우선 cors는 넘겼다.

✅작업 코드(axios)

import axios from "axios";

const url = `http://apis.data.go.kr/1262000/CountryBasicService/getCountryBasicList?ServiceKey=${key}&numOfRows=1&pageNo=1`;
**axios**.get(url).then((res) => {
    console.log(res);
});
  • 그래서 axios로 다시 시도를 해봤다. 코드나 URL상 문제가 있으면, fetch로 요청 해서 받은 데이터와 동일하게 나와야 하는거 같은데 아래의 이미지와 같이 내가 원하는 데이터가 아주 잘 출력이 되는 것을 확인 할 수 있다.

✅fetch로 다시 도전!

  • axios로 데이터가 아주 잘 받아와지는 것을 확인하고, fetch로 다시 도전해보기로 했다.
  • 검색을 좀 해보니, Response 메서드를 활용하면 되는 것을 확인했다.
    • response.text() – 응답을 읽고 텍스트를 반환.
    • response.json() – 응답을 JSON 형태로 파싱
  • 내가 사용하고자 했던 API는 데이터타입이 XML이라서, json() 메서드를 사용하면 아래처럼 에러를 보여줬기 때문에, text() 메서드를 사용하여 XML 데이터를 텍스트로 변환하였다.
const API_URL = `http://apis.data.go.kr/1262000/CountryBasicService/getCountryBasicList?ServiceKey=${API_KEY}&numOfRows=1&pageNo=1`;

fetch(API_URL)
  .then((res) => {
      return **res.text();**
  })
  .then((res) => {
      console.log(res);
  });

  • console.log로 찍어보니, 원하는 데이터가 반환된 것을 확인 할 수 있었다.
  • 이제 이 반환 받은 값을 XML 데이터로 파싱후 객체로 반환해줘야 하는데, 이건 구글링해서 코드를 퍼왔다.
    // text -> XML
    function parseXML(data) {
        var xml, tmp;
        if (!data || typeof data !== "string") {
            return null;
        }
        try {
            if (window.DOMParser) {
                // Standard
                tmp = new DOMParser();
                xml = tmp.parseFromString(data, "text/xml");
            } else {
                // IE
                xml = new ActiveXObject("Microsoft.XMLDOM");
                xml.async = "false";
                xml.loadXML(data);
            }
        } catch (e) {
            xml = undefined;
        }
        if (
            !xml ||
            !xml.documentElement ||
            xml.getElementsByTagName("parsererror").length
        ) {
            throw new Error("Invalid XML: " + data);
        }
        return xml;
    }
    
    // XML -> JSON
    function xmlToJson(xml) {
      // Create the return object
      var obj = {};
    
      if (xml.nodeType == 1) {
        // element
        // do attributes
        if (xml.attributes.length > 0) {
          obj["@attributes"] = {};
          for (var j = 0; j < xml.attributes.length; j++) {
            var attribute = xml.attributes.item(j);
            obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
          }
        }
      } else if (xml.nodeType == 3) {
        // text
        obj = xml.nodeValue;
      }
    
      // do children
      // If all text nodes inside, get concatenated text from them.
      var textNodes = [].slice.call(xml.childNodes).filter(function(node) {
        return node.nodeType === 3;
      });
      if (xml.hasChildNodes() && xml.childNodes.length === textNodes.length) {
        obj = [].slice.call(xml.childNodes).reduce(function(text, node) {
          return text + node.nodeValue;
        }, "");
      } else if (xml.hasChildNodes()) {
        for (var i = 0; i < xml.childNodes.length; i++) {
          var item = xml.childNodes.item(i);
          var nodeName = item.nodeName;
          if (typeof obj[nodeName] == "undefined") {
            obj[nodeName] = xmlToJson(item);
          } else {
            if (typeof obj[nodeName].push == "undefined") {
              var old = obj[nodeName];
              obj[nodeName] = [];
              obj[nodeName].push(old);
            }
            obj[nodeName].push(xmlToJson(item));
          }
        }
      }
      return obj;
    }
  • 실제 적용한 코드는 다음과 같다.
    fetch(API_URL)
        .then((res) => {
            return res.text();
        })
        .then((res) => {
            console.log(xmlToJson(parseXML(res)));
        });
  • 그럼 이제 내가 원하는 JSON으로 아주 잘 받아와진다 😊

📌 Fetch

  • ES6부터 들어온 Promise 기반의 Javascript 내장 라이브러리이다.

✨ 장점

  • Javascript 내장 라이브러리이기 때문에, 별도의 설치 및 import가 필요 없다.
  • Promise 기반으로 만들어졌기 때문에 데이터 다루기 편리하다.
  • 내장 라이브러리이기 때문에 업데이트에 따른 에러 방지가 가능하다.

💣 단점

  • 지원하지 않는 브라우저가 존재한다.
  • 오류 상태에 대해 거부하지 않고, 대신 오류 상태 코드를 반환한다. 개발자로서 오류 처리에 대해 더 많은 코드를 작성해야 할 수 있다.
  • 데이터 포맷이 XML이면, 따로 JSON으로 변환하는 과정을 거쳐야 한다.
  • axios에 비해 비교적 기능이 부족하다.

📌 axios

  • Node.js와 브라우저를 위한 Promise API를 활용하는 HTTP 통신 외부 라이브러리이다.
  • 비동기로 HTTP 통신을 할 수 있으며 return을 promise 객체로 해주기 때문에 response 데이터를 다루기 쉽다.

✨ 장점

  • HTTP 상태 코드 200이 아닌 경우 자동으로 오류를 거부한다. 이로 인해 오류 처리가 간편해진다.
  • 자동으로 JSON 데이터를 파싱한다.
  • Promise 기반으로 만들어졌기 때문에 데이터 다루기 편리하다.
  • 브라우저 호환성이 뛰어나다.
  • 요청을 중단할 수 있는 기능이 내장되어 있다.

💣 단점

  • 별도의 라이브러리 설치가 필요하다.
  • 외부 라이브러리이기 때문에 업데이트에 따라 불안정적일 수 있다.
  • Promise 기반이지만, async/await와의 호환성은 Fetch만큼 완벽하지 않다.

0개의 댓글