GraphQL 쿼리는 어떻게 사용할까??

etc-image-0

이 글은 GraphQL API를 이미 도입한 상태에서 사용하는 방법을 설명하는 글 입니다.
만약 GraphQL에 대한 정보가 더 궁금하시거나 도입에 관한 고민을 하고 계시다면 이곳을 봐주세요.

GraphQL의 쿼리

우리는 지정한 모양의 특정 필드를 반환하는 API를 요청할 수 있습니다.
쿼리문은 직관적으로 구성되어있는데, me 스키마 중

{
  me {
    name
  }
}

요청을 받은 GraphQL API는 다음과 같은 결과를 JSON 형식으로 반환합니다.

{
  "me": {
    "name": "Hyesu"
  }
}

쿼리 결과가 정확히 동일한 형태임을 알 수 있는데, 이것이 GraphQL의 핵심입니다.

쿼리 용어

Fields

이곳에서 field는 person.

{
  person { #field
    name
  }
}
{
  "data": {
    "person": {
      "name": "Hyesu"
    }
  }
}

Arguments

필드에 인자를 전달하는 기능을 추가해 특정한 데이터를 요청할 수 있습니다.
인자는 다양한 타입이 될 수 있는데 int형, 열거형 등 다양한 타입을 전달할 수 있습니다.

{
  human(id: "1000") {
    name
    height
  }
}
{
  "data": {
    "human": {
      "name": "Hyesu",
      "height": 180
    }
  }
}

Aliases

결과 객체 필드가 쿼리의 필드 이름과 일치하지만 인자는 그렇지 않기 때문에 다른 인자를 사용해 같은 필드를 직접 쿼리할 수 없습니다. 그렇기 때문에 별칭을 붙여 데이터를 특정할 수 있습니다.

아래의 예제에서 두 person 필드는 충동하지만, 서로 다른 별칭으로 지정할 수 있으므로 한 요청에서 두 결과를 모두 얻을 수 있습니다.

{
  person1: person(id: 1) {
    name
  }
  person2: person(id: 2) {
    name
  }
}
{
  "data": {
    "person1": {
      "name": "Hyesu"
    },
    "person2": {
      "name": "Suhye"
    }
  }
}

Fragments

상대적으로 복잡한 페이지가 있다고 가정해봅시다.
반려동물이 있는 두 사람을 순서대로 요청하다고 해보면 쿼리가 복잡해지며 필드를 최소 두 번 반복해야합니다.

프래그먼트라는 재사용가능한 단위가 GraphQL에 포함된 이유입니다. 프래그먼트를 사용해 위 상황을 해결해봅시다.

{
  leftComparison: person(id: 1) {
    ...comparisonPets
  }
  rightComparison: person(id: 2) {
    ...comparisonPets
  }
}

fragment comparisonFields on Character {
  name
  pets {
    name
  }
}
{
  "data": {
    "leftComparison": {
      "name": "Hyesu",
      "pets": [
        {
          "name": "여름"
        },
      ]
    },
    "rightComparison": {
      "name": "Suhye",
      "pets": [
        {
          "name": "봄"
        },
        {
          "name": "춘"
        },
      ]
    }
  }
}

Operation Name

지금까지는 작업 타입, 작업 이름을 모두 생략한 단축 문법을 사용했지만, 실제 애플리케이션 코드에서는 덜 헷갈리는게 작성하는것이 좋습니다.

query Human{ # 작업 타입, 작업 이름
  person {
    name
    pets {
      name
    }
  }
}
{
  "data": {
    "person": {
      "name": "Hyesu",
      "pets": [
        {
          "name": "여름"
        },
      ]
    }
  }
}

Variables

앞에서 모든 인자를 쿼리 문자열 안에 작성했었습니다. 하지만 대부분의 응용프로그램에서 필드에 대한 인자는 동적입니다.
어떤 사람에 대해 선택할 수 있는 드롭다운, 검색필드, 필터 등이 있을 수 있습니다.

변수를 사용하기 위해선 세 가지 작업을 해야합니다.
1. 쿼리안의 정적 값을 $variableName 으로 변경합니다.
2. $variableName 을 쿼리에서 받는 변수로 선언합니다.
3. 별도의 전송규약(일반적으로는 JSON) 변수에 variableName: value 을 전달하세요.

선언 된 모든 변수는 스칼라, 열거형, input object type이어야 합니다.

//variables
{
  "id": "1"
}
query Human($id: id) {
  person(id: $id) {
    name
    pets {
      name
    }
  }
}
{
  "data": {
    "person": {
      "name": "Hyesu",
      "pets": [
        {
          "name": "여름"
        },
      ]
    }
  }
}

정보가 더 필요하시다면 GraphQL 공식 문서를 참고해주세요.