Web/[JS] Common

GraphQL 2 - 데이터 조회

ihl 2021. 2. 13. 15:56

1. 공용 GraphQL API

  GraphQL 데이터 Query 요청을 실습하기 위해 공용 GraphQL API를 사용해보자. 공용 GraphQL API는 github.com/APIs-guru/graphql-apis에서 찾아볼 수 있다. 나의 경우 포켓몬고 정보를 기반으로 만든 PokeAPI를 사용하였다.

 

GraphiQL

  GraphQL은 Playground나 GraphiQL 같은 내장 UI를 제공하며 우측 Docs 혹은 Schema 탭에서 API 문서처럼 데이터 형식에 대한 설명을 자동으로 제공한다. 따라서 처음 보는 API일지라도 Docs 탭의 설명을 보며 원하는 데이터를 요청할 수 있다.

 

2. Query 기본

Poke API

PokeAPI의 Docs 탭을 보고 위와 같이 그림으로 나타낼 수 있다. 먼저 root 노드인 query는 query-pokemons-pokemon 3가지 경로를 갖고 있다. 이 중 query는 동일한 쿼리를 여러번 사용하기 위한 장치이므로 그림에서는 생략하였다. 클라이언트는 query로 부터 시작하여 원하는 데이터가 있는 곳까지 탐색해나가는 쿼리를 작성하면 된다.

 

피카츄의 특수공격 데이터 검색 쿼리

피카츄의 특수공격을 찾는 쿼리는 위와 같이 작성할 수 있다. 해당 요청은 다음과 같이 구성된다.

  1. query {} 로 쿼리 작성
    • 쿼리 이름을 정할 수 있는데 위에서는 Pika라고 지정하였다. 하지만 쿼리 이름을 지정하지 않아도 상관없다. 
    • query 키워드 자체가 없어도 상관없다.
    • query Pika{ ... }
  2. 조회할 데이터를 지정
    • 괄호()를 이용하여 조회할 데이터의 조건을 걸 수 있다.
    • Docs 탭에서 pokemon 필드 정보를 확인한 후 조건을 지정한다.
      • pokemon(id: String, name: String): Pokemon
      • 위 내용으로 보아 pokemon은 id, name으로 조건을 지정할 수 있다.
      • 리턴은 Pokemon 타입이다.
    • 위에서는 pokemon 이라는 데이터가 조회 대상이며, name이 "Pikachu"이라는 조건을 걸었다.
    • pokemon(name: "Pikachu") { ... }
  3. 조회할 데이터에서 구체적으로 어떤 데이터가 필요한지 필드를 적는다.
    • 현재 레벨에서는 name, classification, types, attacks 만 필요하므로 해당 노드만 적었다.
  4. 원하는 데이터를 얻기 위해 탐색한 노드에서 더 깊숙히 탐색한다.
    • attacks의 경우 하위에 fast, special이라는 노드가 존재한다.
    • 내가 원하는 데이터인 special 노드를 탐색한다.
  5. leaf노드까지 탐색한다.
    • special 항목에는 name, type, damage라는 하위 노드들이 존재한다. 이 중 원하는 노드를 적어준다.
    • leaf 노드라는 것은 자식노드가 존재하지 않는 마지막 노드를 의미한다. name, type, damage는 모두 하위 노드가 존재하지 않는 leaf 노드이다.
    • special의 모든 항목을 가져오고 싶다는 이유로 special 까지만 쓰고 name, type, damage를 안쓰는 것은 불가능하다. special은 leaf 노드가 아니기 때문이다.

 

3. Query의 다양한 기능

 1) 두 종류의 데이터 요청

Pokemons와 Pokemon 가져오기

   쿼리 사용 시 항상 Pokemons 혹은 Pokemon 중 하나의 데이터만 가져올 수 있는 것은 아니다. 위와 같이 두 노드의 데이터를 동시에 불러올 수 있다.

 

 2) 데이터 이름 지정

Pika와 Eve

   기본적으로 응답 데이터 객체의 이름은 쿼리의 필드이름과 동일하다. 따라서 pokemon 으로 쿼리를 보내면 pokemon이라는 속성 안에 응답 객체가 들어있다. 그런데 클라이언트에서 응답객체 이름을 다르게 주고 싶다면 위와 같이 필드 앞에 원하는 이름을 지정할 수 있다. 위 데이터의 경우 pokemon 필드에 Pika, Eve 라는 이름을 각각 붙여주었고, name 필드 또한 myname이라는 이름으로 변경해주었다.

 

  데이터 이름 지정의 부과적인 효과는 같은 필드를 여러개 가져올 수 있다는 점이다. 위 쿼리문에서 Pika와 Eve라는 이름을 지정하지 않으면 에러가 발생한다.

 

3) fragment

fragment 사용

   피카츄와 이브이 데이터 요청 시 필요한 필드인 이름, 분류, 타입을 각각 따로 써주어야했던 것을 위처럼 한 번 fragment로 작성한 후 재사용할 수 있다.

 

4. 기타

 1) Union and Interface

 

Unions and interfaces

Abstract schema types

www.apollographql.com

  유니언 타입과 인터페이스에 대한 내용은 위 문서에서 확인할 수 있다. 유니언 타입과 인터페이스를 간단히 설명하자면 다음과 같다.

 

   Union type이란 여러가지 타입을 하나의 집합으로 묶고 그 중 하나의 타입을 반환한다는 의미이다. 유니언 타입은 인라인 프래그먼트를 사용하여 쿼리를 작성하면 된다. 

 

 Interface는 객체지향의 인터페이스와 유사한 추상적 타입이다. 유사한 클래스들을 만들 때 중복되는 부분을 인터페이스에 모아놓은 후 인터페이스를 상속받는 클래스들을 만들 듯이 GraphQL의 스키마에서 유사하게 사용한다.

 

 2) Mutation

   Mutation은 데이터를 추가하거나 제거하는 등의 처리를 수행할 때 사용한다. 데이터가 수정되는 작업이므로 Poke API를 로컬에 다운받은 후 실습 해볼 것이다.

 

 


참고 서적:

 

웹 앱 API 개발을 위한 GraphQL

“선언형 데이터 페치 방법과 GRAPHQL 서비스 핵심 가이드”GRAPHQL은 REST API와 비교해 데이터를 가져오는 기능이 훨씬 우수하여 웹 앱 API의 새로운 지평을 열었다고 평가받고 있으며, 이를 활용하

book.naver.com