티스토리 뷰

백엔드 or 서드파티 API에 네트워크 요청이 필요한 어플리케이션을 개발할 때, Axios 및 Fetch와 같은 HTTP 클라이언트를 사용합니다. 

 

Fetch와 Axios 모두 Promise 기반의 HTTP 클라이언트입니다. 즉, 이 클라이언트를 이용해 네트워크 요청을 하면 이행(resolve)혹은 거부(reject)할 수 있는 promise가 반환됩니다. 

Fetch API는 모던 브라우저에 내장되어있어 따로 설치할 필요가 없는 반면 Axios는 서드파티 라이브러리로 CDN 또는 yarn 과 같은 패키지매니저를 통해 설치하여 node.js혹은 브라우저 환경에서 사용 가능합니다. 

 

에러 처리에 있어서 Fetch, Axios 모두 이행(resolve)되거나 거부(reject)된 promise를 반환합니다. 

Promise가 거부되면 .catch()를 사용하여 에러를 처리할 수 있습니다. 

Axios로 에러를 처리하는 방법은 Fetch에 비해 더 간결합니다. 

 

Axios의 promise는 상태코드가 2xx 범위를 넘어가면 거부(reject)합니다. 에러 객체에 응답 또는 요청 프로퍼티가 포함되어 있는지 확인하여 에러에 대한 자세한 정보를 확인할 수 있습니다. 

 

Axios 에러 핸들링

.catch((err) => {
// 에러 처리
if (err.response) {
// 요청이 이루어졌고 서버가 응답했을 경우

    const { status, config } = err.response;

    if (status === 404) {
      console.log(`${config.url} not found`);
    }
    if (status === 500) {
      console.log("Server error");
    }

  } else if (err.request) {
    // 요청이 이루어졌으나 서버에서 응답이 없었을 경우
    console.log("Error", err.message);
  } else {
    // 그 외 다른 에러
    console.log("Error", err.message);
  }
});

반면, Fetch는 404 에러나 다른 HTTP 에러 응답을 받았다고 해서 promise를 거부(reject)하지 않습니다. Fetch는 네트워크 장애가 발생한 경우에만 promise를 거부(reject)합니다. 따라서 .then() 절을 사용해 수동으로 HTTP 에러 처리를 해야 합니다. 

 

Fetch 에러 핸들링 

const url = "https://jsonplaceholder.typicode.com/todos";

fetch(url)
  .then((response) => {
    if (!response.ok) {
      throw new Error(
        `This is an HTTP error: The status is ${response.status}`
      );
    }
    return response.json();
  })
  .then(console.log)
  .catch((err) => {
    console.log(err.message);
  });

 응답 블록에서 응답의 ok상태가 false인 경우 .catch 블록에서 처리되는 커스텀 에러를 발생시킵니다. 

fetch 의 성공했을 시 응답값을 보면 ok 와 status 속성은 각각 true와 200 을 갖게됩니다. 만약 잘못된 URL 엔드포인트를 요청했을 경우 false와 404값을 가지게 됩니다. 이에 따라 에러를 따로 핸들링해줘야 합니다. 

 

응답 시간 초과/ 요청 취소에 있어서 Axios는 timeout 속성을 설정 객체에 추가하여 요청이 종료될 때까지의 시간을 밀리초로 설정할 수 있습니다.  아래의 예시는 요청이 4초이상 걸릴 경우 종료하고 console창에 err를 로깅하고 있습니다. 

const url = "https://jsonplaceholder.typicode.com/todos";

axios
  .get(url, {
    timeout: 4000, // 기본 설정은 '0'입니다 (타임아웃 없음)
  })
  .then((response) => console.log(response.data))
  .catch((err) => {
    console.log(err.message);
  });

 

Fetch를 통한 요청을 취소하기 위해서는 AbortController 인터페이스를 사용할 수 있습니다. 

(fetch는 따로 요청 취소나 타임아웃 기능이 존재하지 않습니다.)

const url = "https://jsonplaceholder.typicode.com/todos";

const controller = new AbortController();
const signal = controller.signal;
setTimeout(() => controller.abort(), 4000);

fetch(url, {
  signal: signal,
})
  .then((response) => response.json())
  .then(console.log)
  .catch((err) => {
    console.error(err.message);
  });

controller 객체를 생성하고나서 signal 객체와 abort() 메서드에 접근합니다. 이 signal 객체를 설정 옵션을 통해 fetch()에 넘깁니다. 이렇게 하면 abort 메서드가 호출될 때마다 fetch 요청이 종료됩니다. setTimeout 기능을 사용하여 서버가 4초 ㅣ내에 응답하지 않으면 작업이 종료됩니다.

 

fetch 가 내장 메서드이기 때문에 axios 보다 살짝 더 빠르지만 두 클라이언트 모두 비동기이기 때문에 크게 중요하지 않습니다. 

 

브라우저 지원에 있어서 모두 모던 브라우저에서 지원됩니다. 오래된 환경에서는 ES6 Promise를 지원하지 않기 때문에 폴리필을 사용해야 합니다. 또한, Fetch의 경우는 이전 브라우저에서의 구현을 지원하기 위해 다른 폴리필을 추가해야 합니다. 

-> axios가 fetch보다 더 많은 브라우저에서 지원됩니다. fetch의 경우, Chrome 42+, Firefox 39+, Edge 14+, and Safari 10.1+이상에 지원합니다. 

 

axios는 자동으로 JSON데이터 형식으로 변환되지만 fetch는 .json() 메서드를 사용해야 합니다.

 

+

json() 과 stringify()의 차이점이 제대로 구분되지 않아 따로 찾아본 정보입니다. 

json 메소드가 stringify보다 더 많은 기능을 제공하는 것으로 보입니다. 단순히 JS객체를 JSON화 할때는 stringify()를 반환값으로 Promise 객체가 필요하다면 json()을 사용하면 될 것 같습니다.  

Response.json()

response.json().then(data => {
  // do something with your data
});

응답 JSON 데이터를 JS Object 형식으로 변환하는 메서드입니다. 

JSON.parse() 메서드와 거의 같은 역할을 하지만 Response.json() 메서드에서는 응답 헤더, 바디를 포함한 응답 객체 자체를 받아서 바디만 읽습니다. 또한, JSON 데이터를 변환해서 Promise 객체를 반환하기 때문에 API 호출에서 사용하기 용이합니다. 반면, JSON.parse() 메서드는 응답 바디만 받을 수 있습니다. 

+ 해당 메서드가 Promise객체를 반환하기 때문에 async await문법을 적용한다 했을 때,
await키워드를 const data = await res.json(); 이런 식으로 붙여줄 수도 있겠죠.

 

JSON.parse()

JSON.parse(text[, reviver])

JSON 데이터는 문자열 형식으로 이루어져 있기 때문에 key에 대해 value를 뽑아내는 등 해당 데이터를 사용하려면 변환이 필요합니다. 이 과정에서 parse()메서드를 사용합니다. 주어진 JSON 문자열을 JS Object형식으로 반환해줍니다. 

 

JSON.stringify()

JSON.stringify(value[, replacer[, space]])

JS 값/ 객체를 JSON 문자열로 변환해주는 메서드입니다. 

댓글