[JavaScript] axios로 화면에 데이터 가져오기(The Movie Database 활용)

비얌·2022년 10월 13일
18
post-thumbnail

개요

오늘은 자바스크립트로 axios를 활용하여 The Movie Database(TMDB)라는 무료 오픈 영화 데이터베이스에 있는 데이터를 가져와 볼 것이다. 그리고 가져오는 것뿐 아니라, 화면에 이를 출력해 볼 것이다.

왜 갑자기 이걸 하냐 하면 따라 하며 배우는 리액트 A-Z에서 현재 Netflix 사이트 만들기를 하고 있는데 이때 axios를 활용하여 TMBD에 있는 데이터를 가져다 쓰기 때문이다.

그렇다면 왜 리액트로 실습해보지 않고 자바스크립트로 하는 거냐! 하면 단순하게 리액트가 어려웠기 때문이다. 그래서 자바스크립트로 구현하면서 알아가고자 했다.

아래의 두 단계를 자바스크립트로 구현해보자!

1. TMBD에서 데이터 가져오기(axios 활용)
2. 영화 제목을 화면에 출력하기

그리고 중간중간 나오는 개념은 간단하게 정리하고 넘어갈 것이다. 추가적으로 나오는 개념이 매우 많아서 일단은 간단하게만 알고 넘어가기로 했다.

마지막으로는 코드 리뷰를 받은 내용을 소개하고 리뷰 받은 대로 수정해볼 것이다.



1. TMDB에서 데이터 가져오기

The Movie Database(TMDB)에서 데이터를 가져올 것이다.

이때, API key가 필요하다. 왜 필요하냐면, https://api.themoviedb.org/3/trending/all/week라는 곳에서 데이터를 가져온다고 하자.

이때 이 주소에 가보면 Invalid API key: You must be granted a valid key라는 문구가 나온다. 데이터를 가져가려면 API key가 필요한 것이다.

실제로 접속하려면 https://api.themoviedb.org/3/trending/all/week?api_key={API key}와 같이 주소에 API key를 넣어줘야 한다.


아래에서 API와 API key에 대한 설명을 이어가려고 한다.

1-1. 개념 정리

코드를 작성하기 전에 일단 코드를 작성하는 데에 필요한 개념을 정리하려고 한다. API key, API, axios, async/await에 대해 알아보자.

(1) API key

TMDB에서 데이터를 가져오려면 먼저 API key를 발급받아야 한다. TMDB에 회원가입 후 발급받을 수 있다. API key는 개발자들이 API를 호출할 수 있게 해준다.

여기서 API란 무엇일까?

(2) API

API는 Application Programming Interface(애플리케이션 프로그램 인터페이스)의 줄임말이다.

여기서 인터페이스란, 어떠한 두 가지가 서로 연결되고 영향을 미칠 수 있는 장소/방법/상황을 의미한다. 이때 두 가지는 사람과 사람, 사람과 기계, 기계와 기계가 될 수도 있다.

API 는 응용 프로그램 간에 데이터를 주고받는 방법을 의미한다. 우리가 만든 응용 프로그램이 서버에게 데이터를 요청할 수 있다. 이때는 컴퓨터끼리 데이터를 주고 받는 것이기 때문에 어떠한 양식이 필요하다. 또한 인증된 곳에만 데이터를 제공하게 할 수도 있고, 서버의 트레픽 과부하를 막기 위해 호출 제한을 둘 수 있다. 이렇듯 데이터를 주고받는 양식, 인증, 호출 제한 등 응용 프로그램 간 소통 방법을 API라고 한다.

우리 동네 날씨를 알려주는 프로그램을 만든다고 가정하자. 이때 날씨 정보는 기상청에서 얻을 수 있을 것이다. 기상청에 날씨 정보를 요청해서 응답받은 후, 그 정보를 보여주면 된다. 이때 날씨 정보를 가져올 수 있도록 기상청에서 제공하는 접점을 API라고 한다.

API의 모양http://api.data.go.kr/weather/list와 같이 생겼다. 이렇게 기상청에서 API를 제공해주면 앱에서는 http://api.data.go.kr/weather/list를 요청해서 {"today": "2022-10-13", "weather": "맑음"}과 같은 데이터를 응답받아 사용자에게 보여줄 UI를 개발할 수 있다.


내가 실습한 TMDB에서는 다음과 같은 API를 제공한다. 이를 통해 최근 영화 목록, 영화 세부 사항, 영화 리뷰 등의 데이터를 가져올 수 있다. 아래 사진은 '리액트 A-Z' 교재에서 가져왔다.

(3) axios

axios를 가지고 TMDB의 영화 데이터를 가져올 것이다. 그 전에 axios가 뭔지 알아보자.

axios란, 공식 문서에 의하면 브라우저, Node.js를 위한 Promise API를 활용하는 HTTP 비동기 통신 라이브러리이다.

하지만 간단하게 말하면 The Movie DB API 서버에 “영화 정보 좀 보내줘”라고 axios를 통해 말하면 서버는 “응 여기!” 하며 영화 정보를 axios를 통해 프론트엔드에 보내준다는 뜻이다.


axios를 사용하기 위해서는 서버에 npm install axios로 설치하거나, 클라이언트(html)에 <script src="https://unpkg.com/axios/dist/axios.min.js"></script> 혹은 <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>로 설치할 수 있다.

TMDB에서 영화 데이터를 가져올 것이므로 서버에 데이터를 요청하는 GET을 알아보자. 서버에서 데이터를 가져올 수 있는 GET은 axios.get(url)로 쉽게 구현할 수 있다. 나도 axios.get(url)로 영화 데이터를 가져올 것이다.


(4) async/await

async와 await는 자바스크립트의 비동기 처리 패턴 중 최근에 나온 문법이다.

기존의 비동기 처리 방식인 콜백함수와 프로미스의 단점을 보완하고 개발자가 읽기 좋은 코드를 작성할 수 있게 도와준다.

위에서 아래로 한 줄 한 줄 차근히 읽으면서 사고할 수 있게 코드를 구성하는 방식이 async, await 문법의 목적이라고 한다.

기본 문법은 다음과 같다. 일단 이 정도만 알고 넘어가기로 했다.

async function 함수명() {
  await 비동기_처리_메서드_명();
}

1-2. 코드

(1) 코드는 어떻게 작성했는가?

결론적으로, 코드는 아래와 같이 작성했다. axios.get()으로 서버에서 url에 있는 데이터를 가져왔으며, await을 통해 데이터를 가져올 때까지 기다리게 했다. 그리고 가져온 데이터를 response라고 칭하기로 했다.

영화 데이터를 10개만 가져오도록 했고, 영화 데이터 중 제목만을 출력하도록 했다. 원래 .title라고 하면 제목을 출력할 수 있는데, 몇몇 영화는 title이 아니라 name이라는 변수에 제목을 담고 있었다. 그래서 .title을 받아왔을 때 undefined라는 결과가 나오면 제목이 title이 아니라 name에 있기 때문에 .name을 통해 영화 제목을 가져왔다.(if-else문)

const key = "발급받은 TMDB API key 복붙";

const fetchMovie = async() => {
  const url = "https://api.themoviedb.org/3/trending/all/week?api_key=" + key + "&language=ko-KR"
  const response = await axios.get(url);
  for(let i=0; i<10; i++) {
    if (response.data.results[i].title == undefined) {
      console.log(response.data.results[i].name)
    }
    else {
      console.log(response.data.results[i].title)
    }
  }
}

결과

10개의 영화 제목이 콘솔 창에 잘 출력됐다!



2. 영화 제목을 화면에 출력하기

이제 가져온 데이터를 콘솔 창이 아닌 화면에 출력할 것이다. 좀 더 디테일을 주기 위해, 최신 영화 10선 불러오기라는 버튼을 클릭하면 그 아래에 영화 제목 10개를 출력해주려고 한다.

2-1. 쓸 함수 설명

여기서 사용할 함수는 다음과 같이 다섯 개이다.

  • document.getElementById(id): id 속성을 사용하여 해당 태그에 접근하여 작업할 수 있다.

  • document.onclick()="function()": document 객체가 클릭 되면 function 함수를 실행한다.

  • document.createElement(tagName[, options]): 지정한 tagName의 HTML 요소를 만들어 반환한다.

  • node.textContent: node의 텍스트값을 읽어오고 설정할 수 있다.
    element.innerHTML과 비슷하지만 textContentinnerHTML에 비해 xss라는 보안상 위협이 없고 성능이 더 좋다고 한다.

  • node.appendChild(): 부모 노드에 자식 노드를 추가한다.


2-2. 코드

완성된 코드는 아래와 같다. '최신 영화 10선 불러오기'라고 써진 버튼을 만들고 버튼이 클릭 되면 함수가 실행되게 했다.

10개의 영화 제목을 가져오는데, for 문을 돌며 매번 h3 태그를 만들고 이에 제목을 쓰고, 다음 h3 태그를 그 아래에 이어붙이는 것을 반복했다.

const key = "발급받은 TMDB API key 복붙";

document.getElementById("get-button").onclick = function () {
  const fetchTrending = async() => {
    const url = "https://api.themoviedb.org/3/trending/all/week?api_key=" + key + "&language=ko-KR"
    const response = await axios.get(url);
    for(let i=0; i<10; i++) {
      if (response.data.results[i].title == undefined) {
        newH3 = document.createElement('h3')
        newH3.textContent = response.data.results[i].name
        document.body.appendChild(newH3);
      }
      else {
        newH3 = document.createElement('h3')
        newH3.textContent = response.data.results[i].title
        document.body.appendChild(newH3);
      }
    }
  }
  fetchTrending()
};

결과

버튼을 누르면 10개의 영화 제목을 화면에 출력하는 데 성공했다!



💡 3. 코드 리뷰를 받았다

위의 자바스크립트 코드에 대한 코드 리뷰를 받았다.

3-1. 코드 리뷰 내용

  1. 이벤트 리스너는 onclick에 = 해서 넣는 것보다 addEventListener('click', fn) 형태로 넣는 것이 더 선호된다.

    👉 이유는, 이벤트 리스너를 여러 개 붙일 수 있다는 점이나, 아니면 addEventListener의 3번째 인자에 각종 옵션을 넘겨서 특수한 동작을 의도할 수 있다는 점 등 addEventListener가 상대적으로 더 많은 기능을 가지고 있어서 보통 이쪽으로 통일해서 사용하는 편이다.

  2. 핸들러 자체는 일반 function이고 내부에 async 화살표 함수를 정의해서 이걸 부르는 방식으로 하고 있는데, 그냥 이벤트 핸들러를 async 함수로 만들어도 이 경우에는 특별히 이상 없이 잘 작동한다.

  3. URL 만들 때 Template Literal 문자열을 사용하면 좀 더 이쁘게 만들 수 있을 것 같다

  4. for 문 돌 때 지금처럼 하면 results 안에 값이 10개보다 적게 들어 있을 때 에러가 난다. (처음 알았음!)

    👉 for문을
    for (let i = 0; i < Math.min([http://response.data](https://t.co/Oow8XVepID).results.length, 10); i++) 로 바꾸거나, for (const result of [http://response.data](https://t.co/Oow8XVepID).results.slice(0, 10))으로 바꾸고 내부에서 result를 사용하는 방법이 있다.

  5. if랑 else에서 각각 첫 줄과 셋째 줄이 중복되는데 첫 줄과 셋째 줄을 if 문밖으로 빼고 if 안에는 textContent 설정하는 거만 남겨 두면 코드 중복을 줄일 수 있다.


3-2. 고친 코드

피드백 받은 다섯 가지를 모두 고쳤다! 모두 정상적으로 작동한다.

const key = "발급받은 TMDB API key 복붙";

document.getElementById('get-button').addEventListener('click', async function getUrl() {
    const url = `https://api.themoviedb.org/3/trending/all/week?api_key=${key}&language=ko-KR`
    console.log(url);
    const response = await axios.get(url);
    console.log(response);
    for(let i=0; i<Math.min(response.data.results.length, 10); i++) {
      newH3 = document.createElement('h3')
      if (response.data.results[i].title == undefined) {
        newH3.textContent = response.data.results[i].name
      }
      else {
        newH3.textContent = response.data.results[i].title
      }
      document.body.appendChild(newH3);
    }
})


🐹 회고

axios를 예전에 배우다가 너무 어려워서 포기했었는데, 이번에는 포기하지 않고 공부해서 많은 것들을 알게 되어서 좋았다. (모든 것을 이해하겠다는 생각보다는 이번에 대략 이해하고 다음번에 더 많이, 그 다음번엔 더욱 많이 이해해야겠다고 생각했다.)

그리고 axios를 공부하며 평소에 이해되지 않던 API에 대해 이해한 것 같아 뿌듯했다.

자바스크립트를 잘 모르고 리액트를 공부한다는 생각 때문에 자바스크립트 공부에 대해 부채감을 느꼈는데, 이렇게 조금씩 해나가면 좋을 것 같다. 이번 기회를 통해 자바스크립트와 조금 더 가까워진 기분이 들어 좋았다.

코드 리뷰해주시고 질문받아주신 시니하님, axios에 대해 이해할 수 있게 설명해주신 썰님 감사합니다!!


참고

  1. [API]1. API란 무엇일까?
  2. API란 무엇인가? | 초보자를 위한 쉬운 개념 정리!!
profile
🐹강화하고 싶은 기억을 기록하고 공유하자🐹

6개의 댓글

comment-user-thumbnail
2022년 10월 13일

넘넘 깔끔하게 잘쓰셨네요 맛있게 잘 읽고 가여~~!

1개의 답글
comment-user-thumbnail
2022년 10월 13일

벨로그 최고의 블로거직직..
그리고 정말 제가 가장 어려워하는 부분이에요.........

1개의 답글
comment-user-thumbnail
2022년 10월 18일

잘읽었습니다

1개의 답글