[GQL]Graphql 맨바닥에 부딪치기(2) - 실전 Query

March 16, 2021 ( last updated : March 16, 2021 )
Graphql gql 그래프큐엘 김혜원

https://github.com/sneakstarberry/


Abstract

김혜원이 배워가고 싶다고 해서 시작된 포스트

[GQL]Graphql 맨바닥에 부딪치기(2)

query에 대한 개념은 충분히 익혔으므로 이제 실전에 적용해보겠습니다. 이번 프로젝트에서 사용한 패키지는 apollo에서 나온 Graphql패키지로 해당 패키지를 인스톨하기 위해서는 다음과 같이 하면됩니다.

npm install @apollo/client graphql

이제 부터 쿼리를 써보겠습니다.

import { gql, useQuery } from '@apollo/client';

const GET_DOGS = gql`
  query GetDogs {
    dogs {
      id
      breed
    }
  }
`;

위와 같이 보낼 쿼리는 gql 함수로 감싸 준다. 그리고 실제로 보내주는 함수는 다음과 같이 생성한다.

function Dogs({ onDogSelected }) {
  const { loading, error, data } = useQuery(GET_DOGS);

  if (loading) return 'Loading...';
  if (error) return `Error! ${error.message}`;

  return (
    <select name="dog" onChange={onDogSelected}>
      {data.dogs.map(dog => (
        <option key={dog.id} value={dog.breed}>
          {dog.breed}
        </option>
      ))}
    </select>
  );
}

useQuery 훅을 통해서 간단히 요청하고 data로 response 데이터를 이용할 수 있다. 해당 데이터를 이용할 때 주의 할 점은 바로 계층 구조이다.

data에서 바로 id 혹은 breed를 바로 쓸 수 없다. data.id 혹은 data.breed는 안된다는 것이다. 쿼리에 쓴 dogs를 넘어가야지 idbreed를 쓸 수 있다. 언듯 보면 너무나도 당연한 사실처럼 느껴지지만 나를 포함한 모든 팀원들이 한번 씩 착각을 했다.

위 코드들은 js를 가정하고 쓰여진 코드들이다. 그렇다면 ts 개발 환경에서는 어떻게 해야할까? useQuery훅이 제네릭 함수이기 때문에 우리는 타입을 변수로 주면된다. 먼저 함수의 형태이다.

useQuery에서 첫번째 타입 변수는 리턴될 데이터의 타입을 주고 두번째 타입 변수는 변수의 타입 변수를 줍니다.

useQuery<리턴 타입, 변수 타입>(쿼리문, {옵션들(변수, 리패칭 등)})

이제 실제로 어떻게 쓰는지 예제를 통해 확인 해보겠습니다.

import React from 'react';
import { useQuery, gql } from '@apollo/client';

interface RocketInventory {
  id: number;
  model: string;
  year: number;
  stock: number;
}

interface RocketInventoryData {
  rocketInventory: RocketInventory[];
}

interface RocketInventoryVars {
  year: number;
}

const GET_ROCKET_INVENTORY = gql`
  query GetRocketInventory($year: Int!) {
    rocketInventory(year: $year) {
      id
      model
      year
      stock
    }
  }
`;
...

예제 코드가 너무 길어서 타입과 쿼리 선언부만 가져왔습니다. 쿼리는 평범하지만 interface를 선언해주는 것을 보았을 것입니다. 가져올려는 쿼리의 구조에 따라서 interface를 작성하면됩니다. 변수의 interface 또한 적어줍니다. 이후 useQuery의 타입 변수에 넣어줍니다.

export function RocketInventoryList() {
  const { loading, data } = useQuery<RocketInventoryData, RocketInventoryVars>(
    GET_ROCKET_INVENTORY,
    { variables: { year: 2019 } }
  );
  ...

함수는 위의 형태로 사용 됩니다.

Originally published March 16, 2021
Latest update March 16, 2021

Related posts :

{# #}