# 184 [udemy React 완벽 가이드 노트] SWAPI (The Star Wars API) axios, fetch API, async await
더미 API를 제공하는 사이트
전송요청을 해서 실습 해볼 수 있다.
데이터베이스가 아니고 백엔드 앱이다.
이 것의 백그라운드에서는 아마도 스타워즈 데이터를 저장하기 위해
데이터베이스를 사용할 것이다.
API : 어플리케이션 프로그래밍 인터페이스
리액트, HTTP요청 뿐만 아니라 코드를 통해 명확하게 정의된 인터페이스를 다루며,
어떤 결과를 얻기 위한, 작업에 대한 규칙이 명확하게 정의를 다룬다.
HTTP요청에 대한 API를 말할 때는 보통 REST, Graph QL API를 말한다.
이 두 개는 서버가 데이터를 노출하는 방식에 대한 서로 다른 표준이다.
SWAPI는 REST이며
URL같은 곳에 요청을 하게 되면
특정한 형식에 맞춰 데이터를 전달해 준다.
서로 다른 URL에 다른 요청을 보내면 그에 맞는 서로 다른 데이터들을 제공한다.
이것이 API이다.
접근 위치가 다르면 결과도 다르다.
이제 리액트 어플리케이션에서 이 API로 요청을 보내서
실제 데이터를 표시해본다.
리액트에서 요청 보내기
자바스크립트 코드를 작성한다.
리액트는 자바스크립트 어플리케이션이며
자바스크립트 솔루션을 통해 어떤 HTTP요청이든 전달할수 있다.
1. 리액트 패키지 axios
어떤 자바스크립트 라이브러리를 사용하는가에 관계없이 http요청 전송을 하고
response를 받을 수 있는 패키지다.
2. http요청을 전송하는 내장 메커니즘 Fetch API
브라우저 내장형
데이터를 불러오고 데이터 전송도 가능하다.
이 API를 통해 http요청을 전송하고 응답을 처리할 수 있다.
우리는 이 Fetch API를 강의에서 사용해 볼것이다 .
버튼이 클릭될 때마다 영화정보를 가져오고,
영화정보 결과를 화면에 표시하는 것
함수 fetchMoviesHandler를 사용하기
그 안에서 fetch를 사용할 수 있다.
브라우저가 사용할 수 있게 해 준 함수.
fetch API를 사용하는 것
그 안에 요청하려는 URL을 문자열로 전달한다.
function fetchMoviesHandler() {
fetch('https://swapi.dev/api/films');
}
이 함수가 호출될 때마다 http 리퀘스트를 보낼 것이다.
그리고 우리는 response에 대해 다뤄야 한다.
fetch는 promise를 반환하는데 그것은
response나 발생할 수 있는 잠재적 오류에 대해 반응을 할 수 있게 해준다.
이제 promise를 받게 될 것인데, 그 객체는 즉각적 반응 대신 결국 데이터를 전달한다
HTTP요청을 전송하는 것은 비동기작업이다.
즉각 끝나는 작업이 아니다.
몇 밀리 초, 혹은 몇 초가 걸리는 작업이고
실패로 끝날 수도 있다.
다음 줄에 작업을 계속 해서 코드 결과를 바로 사용할 수 없다.
대신 그 곳의 코드 실행 결과를 미래 어느 시점에서 확인할 수 있다.
자바스크립트에 프로미스가 있는 이유다.
then ( )
function fetchMoviesHandler() {
fetch('https://swapi.dev/api/films/').then();
}
그래서 fetch뒤에 then 함수를 정의한다. 이 함수는 우리가 응답을 받을 때 호출될 것이다.
우리는 response를 받아 화살표함수를 작성하고
그 함수 안에 response를 사용할 수 있다.
response 인자는 객체며, response에 대한 한 덩어리의 데이터다.
우리는 response의 headers를 읽을 수 있고 status 코드를 받을 수 있고,
ok영역은 모든 것이 정상이면 true, 그렇지 않으면 false를 반환한다.
API는 데이터를 JSON형식으로 전송해준다.
데이터를 전송하는 형식이다.
자바스크립트 객체같지만 key값은 큰 따옴표로 묶여있다.
모두 메서드가 아닌 데이터다.
자바스크립트로 변환작업이 필요하지만
자바스크립트 객체로 바꾸기 매우 용이하다.
.json() 메서드
이 response 객체에는 JSON의 본문을 자바스크립트 객체로
자동 변환해주는 내장 메서드가 있다.
function fetchMoviesHandler() {
fetch('https://swapi.dev/api/films/').then(response => {
return response.json();
});
.json() 메서드다.
promise를 return해주고 또다른 then( ) 구역을 생성한다.
그러면 데이터 변환작업이 끝날 때 작동하게 된다.
우리가 원하는 것은 response.json() 의 results의 배열이므로
다음과 같이 작성해준다.
function App() {
function fetchMoviesHandler() {
fetch('https://swapi.dev/api/films/').then(response => {
response.json();
}).then(data => {
data.results
});
}
그래서 그 결과를
return (
<>
<section>
<button>Fetch Movies</button>
</section>
<section>
<MoviesList movies={ } />
</section>
</>
);
MoviesList의 movies에 저장해 주기로 한다.
그러려면 useState를 import해주고,
useState를 빈 배열로 초기화 해주고,
이름을 movies와 setMovies로 저장한다 .
function App() {
const [movies, setMovies] = useState([])
그리고 파싱 후 추출된 영화를 전달받으면
setMovies를 호출해
data.results를 설정해준다.
function fetchMoviesHandler() {
fetch('https://swapi.dev/api/films/').then(response => {
response.json();
}).then(data => {
setMovies(data.results)
});
}
그렇게 되면 새로운 movies state가 설정된다.
들어오는 releaseDate는 release_date로 되어있기 때문에 Movie의 이름을 바꾸거나
다른 방법으로 들어오는 데이터의 형식을 바꿔서 원하는 형식으로 변환해야 한다.
App.js 안에서 HTTP요청을 하고 있는 곳에다가
data.results로 만들기 전에 map 함수를 사용해 각각 변경해 새로운 객체를 만들자.
그리고 그 함수를 setMovies에 넣어준다.
그리고 button에 onClick 이벤트로 fetchMoviesHandler에 연결해준다.
그러면 버튼을 클릭할 때마다 데이터를 fetch해 올 것이다.
import React, { useState } from "react";
import "./App.css";
import MoviesList from "./components/MoviesList";
function App() {
const [movies, setMovies] = useState([]);
function fetchMoviesHandler() {
fetch("https://swapi.dev/api/films/")
.then(response => {
response.json();
})
.then(data => {
const transformedMovies = data.results.map(movieData => {
return {
id: movieData.episode_id,
title: movieData.title,
openingText: movieData.opening_crawl,
releaseData: movieData.release_date,
};
});
setMovies(transformedMovies);
});
}
return (
<>
<section>
<button onClick={fetchMoviesHandler}>Fetch Movies</button>
</section>
<section>
<MoviesList movies={movies} />
</section>
</>
);
}
export default App;
리액트 앱을 이용해
데이터베이스와 연결해 보았다.
정확히 말해,
HTTP요청을 전송하는 방법을 배워보았다.
async와 await 로 사용할 수도 있다.
async function fetchMoviesHandler() {
const response = await fetch("https://swapi.dev/api/films/")
const data = await response.json();
const transformedMovies = data.results.map(movieData => {
return {
id: movieData.episode_id,
title: movieData.title,
openingText: movieData.opening_crawl,
releaseData: movieData.release_date,
};
});
setMovies(transformedMovies);
}