Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

JavaScript GET 요청 완벽 가이드: Fetch API로 데이터 불러오기

개발자라면 자신이 만든 API나 서드파티(외부) API에서 데이터를 가져와야 하는 상황을 자주 마주하게 됩니다. 이 글에서는 브라우저에 내장된 Fetch API를 사용해 엔드포인트(endpoint)로부터 GET 요청으로 데이터를 받아오는 방법을 알아보겠습니다.

Fetch API란 무엇인가?

Fetch API는 Chrome이나 Firefox 같은 웹 브라우저에서 서버로 HTTP 요청을 보낼 수 있게 해주는 인터페이스입니다. GET 요청은 서버의 특정 엔드포인트에 접근한 뒤, 해당 엔드포인트가 가진 데이터를 응답(response) 형태로 반환하므로 이를 화면에서 읽고 활용할 수 있습니다.

HTTP 요청의 종류

GET 요청은 서버에 보낼 수 있는 여러 요청 중 하나일 뿐입니다. 그 외에도 POST, PUT, DELETE 요청이 있으며, 이 네 가지를 조합하면 CRUD 애플리케이션을 만들 수 있습니다. 즉, 데이터베이스에서 데이터를 생성(Create, POST)하고, 조회(Read, GET)하고, 수정(Update, PUT)하고, 삭제(Delete, DELETE)하는 것이죠.

또한 서드파티 API의 엔드포인트에도 요청을 보낼 수 있습니다. 다만 API마다 정책이 다르기 때문에 특정 요청만 허용되는 경우가 많습니다. 주로 자신들의 데이터를 변경 불가능한 상태로 유지하려는 목적 때문인데, 이런 경우에는 데이터를 조작하는 요청은 할 수 없고 읽기(GET)만 가능합니다.

Fetch API는 어떻게 동작할까?

Fetch API는 프로미스(Promise) 기반 통신 시스템을 사용합니다. 잠시 복습하자면, 프로미스는 비동기 로직을 하나의 코드 블록 안에 캡슐화하고, 그 결과가 성공(resolve)했는지 실패(reject)했는지를 나타내는 응답을 반환하는 비동기 함수입니다.

다행히 Fetch API 사용자 입장에서는 프로미스 로직을 직접 작성할 필요가 없습니다. 단순히 요청을 보내면 Fetch API가 내부적으로 프로미스를 반환해주기 때문입니다. 기본 문법은 다음과 같습니다.

promise.then(response).then(json).catch(error);

여기서 프로미스는 실제 비동기 요청을 의미하며, 전역 스코프(global scope)에서 사용 가능한 fetch() 메서드에 HTTP 요청을 보낼 엔드포인트 URL을 인자로 전달합니다.

let promise = fetch("https://swapi.dev/api/films/1");

요청을 보낸 후에는 thencatch를 사용하는 프로미스 문법 또는 async/await 함수를 사용해 서버의 응답을 받아올 수 있습니다.

Promise 문법 사용하기

promise.then(response => {
  if (response.status !== 200) {
    console.log('문제가 발생했습니다. Status Code: ' + response.status);
    return;
  }
  response.json().then(data => {
    console.log(data);
  }).catch(error => {
    console.log(error.message);
  })
})

위 코드는 프로미스를 받아 응답을 기다립니다. 응답을 받았을 때 상태 코드(status code)가 200이 아니면 콘솔에 에러 코드를 출력하고 함수를 종료합니다.

상태 코드가 200이라면, 프론트엔드에서 활용할 수 있도록 응답을 json() 메서드로 변환해 읽을 수 있는 형태로 만듭니다. 이 변환이 먼저 처리된 후 다음 단계로 넘어가야 하기 때문에, 앞선 프로미스에 새로운 프로미스를 체이닝(chaining)합니다.

변환이 완료되면 전달받은 데이터를 콘솔에 출력해 확인할 수 있습니다. 직접 따라 해보면 아래와 같은 결과를 얻게 됩니다.

{
  title: 'A New Hope',
  episode_id: 4,
  opening_crawl: 'It is a period of civil war...',
  director: 'George Lucas',
  producer: 'Gary Kurtz, Rick McCallum',
  release_date: '1977-05-25',
  characters: [
    'https://swapi.dev/api/people/1/',
    'https://swapi.dev/api/people/2/',
    ...
  ],
  planets: [
    'https://swapi.dev/api/planets/1/',
    ...
  ],
  starships: [
    'https://swapi.dev/api/starships/2/',
    ...
  ],
  vehicles: [
    'https://swapi.dev/api/vehicles/4/',
    ...
  ],
  species: [
    'https://swapi.dev/api/species/1/',
    ...
  ],
  created: '2014-12-10T14:23:31.880000Z',
  edited: '2014-12-20T19:49:45.256000Z',
  url: 'https://swapi.dev/api/films/1/'
}

이렇게 프론트엔드에서 데이터를 받아오면 카드 UI나 테이블 등 원하는 방식으로 화면에 표시할 수 있습니다.

Async/Await 사용하기

같은 결과는 async/await 함수로도 얻을 수 있습니다.

let getRequest = async () => {
  try {
    let fetched = await fetch("https://swapi.dev/api/films/1");
    if (fetched) {
      let read = await fetched.json()
      console.log(read);
      return read;
    }
  }
  catch (error) {
    throw new Error(error.message);
  }
}
 
getRequest()

async 키워드는 해당 함수의 일부가 비동기적으로 실행됨을 의미합니다. 그리고 실행 흐름이 await 키워드를 만나면, 해당 코드 라인의 평가가 완료될 때까지 스크립트 실행이 일시적으로 멈춥니다.

이 함수에는 두 개의 await 구문이 있는데, 이는 프로미스 로직에서 사용했던 두 개의 then() 구문과 대응됩니다. 하나는 전달한 URL에서 데이터를 가져오는(fetching) 작업을 기다리고, 다른 하나는 가져온 정보가 JSON으로 파싱될 때까지 기다립니다. 또한 try/catch를 사용해 응답에서 예상치 못한 값이 돌아올 경우 발생할 수 있는 에러를 처리합니다.

마무리하며

Node 환경(예: Visual Studio Code 같은 IDE)에서 Fetch API를 사용하려면 yarn add node-fetch 또는 npm install node-fetch 명령으로 node-fetch 패키지를 설치해야 합니다. 기본 fetch()는 오직 브라우저 환경에서만 동작하기 때문입니다.

정리하자면, Fetch API는 프로미스 기반으로 동작하며 then/catch 체이닝 또는 async/await 문법 어느 쪽이든 깔끔하게 GET 요청을 처리할 수 있습니다. 두 방식 모두 익혀두면 상황에 맞게 선택해 사용할 수 있습니다.