TIL/etc.

[TIL] API

Dong _ hwa 2023. 5. 18. 20:05

๐Ÿ‘จ‍๐Ÿ’ป React HTTP ์š”์ฒญ ๋ณด๋‚ด๊ธฐ

  • ํด๋ผ์ด์–ธํŠธ์— ์ง์ ‘์ ์œผ๋กœ ์„œ๋ฒ„๋ฅผ ์—ฐ๊ฒฐํ•˜๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋Š” ๋ˆ„๊ตฌ๋‚˜ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ธ์ฆ ์ •๋ณด๋ฅผ ๋…ธ์ถœ์‹œํ‚ค๋Š” ํ–‰์œ„์ด๋ฉฐ ๋ณด์•ˆ์— ์ทจ์•ฝํ•ด์ง„๋‹ค.
  • HTTP ์š”์ฒญ์— ๋Œ€ํ•œ API๋ฅผ ๋งํ•  ๋•Œ๋Š” ๋ณดํ†ต REST ๋˜๋Š” GraphQL API๋ฅผ ๋งํ•˜๋ฉฐ ์ด ๋‘ ๊ฐœ๋Š” ์„œ๋ฒ„๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ๋…ธ์ถœํ•˜๋Š” ๋ฐฉ์‹์— ๋Œ€ํ•œ ์„œ๋กœ ๋‹ค๋ฅธ ํ‘œ์ค€์ด๋‹ค.
  • Fetch API๋Š” ๋ธŒ๋ผ์šฐ์ € ๋‚ด์žฅํ˜•์ด๋ฉฐ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ณ  ์ด๋ฆ„๊ณผ๋Š” ๋‹ค๋ฅด๊ฒŒ ์ „์†ก๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

์‚ฌ์šฉํ•œ API์ฃผ์†Œ : https://swapi.dev/
API ์„ค๋ช…: ์˜ํ™”์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ JSONํ˜•์‹์œผ๋กœ ๋ณด์—ฌ์คŒ

์˜ํ™”์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋ถˆ๋Ÿฌ์™€ ๊ทธ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๊ฐ„๋‹จํ•œ ํ•จ์ˆ˜

const [movies, setMovies] = useState([]);

// ์ด์ œ ์ด ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ ๋งˆ๋‹ค ๋งค ๋ฒˆ HTTP ์š”์ฒญ์ด ์ „์†ก๋จ
function fetchMoviesHandler () {
  // fetch๋ฅผ ํ†ตํ•ด ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•จ
  fetch('https://swapi.dev/api/films/')
  // *์ค‘์š”* ์™œ? then์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋ƒ? - HTTP ์š”์ฒญ์€ ์ฆ‰๊ฐ ๋๋‚˜๋Š” ์ž‘์—…์ด ์•„๋‹ˆ๊ธฐ์— ๋ฏธ๋ž˜์˜ ์–ด๋А ์‹œ์ ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Œ
  // ์ด ๋ง์€ ์ฆ‰, ๋๋‚˜๋Š” ์‹œ์ ์— ๋งž์ถฐ then์„ ์ด์šฉํ•˜์—ฌ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์•ผํ•จ

  // ์š”์ฒญ ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋Š” JSON ํ˜•์‹์ด๋ฏ€๋กœ ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด๋กœ ๋ฐ˜ํ™˜ํ•จ
  .then(response => response.json())
  // ๊ทธ ๋ณ€ํ™˜๋œ ๋ฐ์ดํ„ฐ๋ฅผ useState๋กœ movies์— ๋„ฃ์–ด์คŒ
  .then((data) => {
    setMovies(data.results);
  }
}





์œ„ ์ฒ˜๋Ÿผ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ”๋กœ ๋„ฃ์–ด์ค„ ์ˆ˜ ์žˆ๊ฒ ์ง€๋งŒ ์‹ค์ œ๋กœ ์งœ์—ฌ์ง„ ์ฝ”๋“œ์™€ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋ฐ์ดํ„ฐ์—์„œ ํ‚ค ๊ฐ’์— ์ฐจ์ด๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค.
๊ทธ๋Ÿฌ๋ฏ€๋กœ map์„ ์ด์šฉํ•˜์—ฌ ์›๋ž˜ ์งœ์—ฌ์ง„ ํ‚ค ๊ฐ’์— ๋งž์ถฐ์ฃผ๋Š” ๊ฒŒ ์ข‹๋‹ค.
(๋ฌผ๋ก , ๋ฐ›์•„์˜ค๋Š” ๋ฐ์ดํ„ฐ์˜ ํ‚ค ๊ฐ’์— ๋งž๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ๋‹ค.)

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,
        releaseDate: movieData.release_date
      };
    });
    setMovies(transformedMovies);
  }
}



์ดํ•ด๋ฅผ ์œ„ํ•œ ๋”๋ฏธ๋ฐ์ดํ„ฐ์™€ API ์š”์ฒญ์— ์˜ํ•ด ๊ฐ€์ ธ์˜จ ๋ฐ์ดํ„ฐ ๋น„๊ต



  • ์œ„์˜ fetch๋ฅผ ์ด์šฉํ•œ ๋ฐฉ๋ฒ•๊ณผ ๋˜‘๊ฐ™์ด async, await๋ฅผ ์ด์šฉํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ด๊ฑด ๋ฆฌ์•กํŠธ์˜ ํŠน๋ณ„ ๊ธฐ๋Šฅ์ด ์•„๋‹Œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๊ธฐ๋ณธ ๊ธฐ๋Šฅ์ด๋‹ค.
  • ์‹ค์ œ๋กœ ์ด ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋  ๋• then์œผ๋กœ ๋ฒˆ์—ญ๋˜์–ด ์‹คํ–‰๋œ๋‹ค.
const [movies, setMovies] = useState([]);

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,
      releaseDate: movieData.release_date
    };
  });
  setMovies(transformedMovies);
}




๋กœ๋”ฉ ํ™”๋ฉด ๊ตฌํ˜„ํ•˜๊ธฐ ๐Ÿ’ญ

const [movies, setMovies] = useState([]);
const [isLoading, setIsLoading] = useState(false);

async function fetchMoviesHandler () {
  // ์•„๋ž˜์˜ ์ฝ”๋“œ๋“ค์ด ์‹คํ˜„๋˜๊ธฐ ์ „์— ๋กœ๋”ฉ ์ƒํƒœ๋ฅผ true๋กœ ๋งŒ๋“ฌ
  setIsLoading(true);
  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,
      releaseDate: movieData.release_date
    };
  });
  setMovies(transformedMovies);
  // ๋ชจ๋“  ์ฝ”๋“œ๊ฐ€ ๋Œ์•„๊ฐ”๋‹ค๋ฉด ๋‹ค์‹œ ๋กœ๋”ฉ ์ƒํƒœ๋ฅผ false๋กœ ๋งŒ๋“ฌ
  setIsLoading(false);
}

const App () => {
  return (
    <React.Fragment>
      // ๋กœ๋”ฉ ์ƒํƒœ๊ฐ€ false์ผ ๊ฒฝ์šฐ MovieList ์ปดํผ๋„ŒํŠธ๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ 
      {!isLoading && <MovieList/>}
      // ๋กœ๋”ฉ ์ƒํƒœ๊ฐ€ true์ผ ๊ฒฝ์šฐ LoadingPage ์ปดํผ๋„ŒํŠธ๋ฅผ ๋ณด์—ฌ์คŒ
      {isLoading && <LoadingPage>}
    </React.Fragment>
  )
}



  • ์ถ”๊ฐ€๋กœ ์ปจํ…์ธ ๊ฐ€ ์—†์„ ๊ฒฝ์šฐ์˜ ํ™”๋ฉด๋„ ๋‚˜๋ˆ„๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ๋‹ค.
  • ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด๊ถ๋ฌด์ง„ํ•˜๋‹ค.
const App () => {
  return (
    <React.Fragment>
      // ๋กœ๋”ฉ์€ ๋˜์—ˆ๊ณ  ๋ณด์—ฌ์ค„ ๋‚ด์šฉ์ด ์žˆ๋Š” ๊ฒฝ์šฐ
      {!isLoading && movies.length > 0 && <MovieList/>}
      // ๋กœ๋”ฉ์€ ๋˜์—ˆ์ง€๋งŒ ๋ณด์—ฌ์ค„ ๋‚ด์šฉ์ด ์—†๋Š” ๊ฒฝ์šฐ
      {!isLoasing && movies.length === 0 && <EmptyList/>}
      // ๋กœ๋”ฉ์ด ์•ˆ ๋œ ๊ฒฝ์šฐ
      {isLoading && <LoadingPage>}
    </React.Fragment>
  )
}