Code

GraphQL Introduction

December 10, 2016

author:

GraphQL Introduction

이 글은 GraphQL 튜토리얼을 보고 간단하게 정리한 글입니다.
문법의 기능적인 부분만 중점적으로 추려냈으니, 장단점에 대한 설명이 필요하시다면 원문을 참고하세요.

코드도 원문을 인용했습니다. 다만 몇몇 긴 부분은 추려서 줄였습니다.

Queries and Mutation

Fields

  • GraphQL은 객체의 특정 필드에 대한 정보를 질의하는 것
  • 그런 이유로 와일드카드는 존재하지 않음
  • 요청과 결과가 비슷함
  • 중첩된 객체를 가져올 수 있음
// Query
{
  hero {
    name
    # Queries can have comments!
    friends {
      name
    }
  }
}

// Result
{
  "data": {
    "hero": {
      "name": "R2-D2",
      "friends": [
        {
          "name": "Luke Skywalker"
        },
        {
          "name": "Leia Organa"
        }
      ]
    }
  }
}

Arguments

  • 해당 타입에서 원하는 것만 가져올 수 있음.
  • <type>(<attr>: <value>)
// Query
{
  human(id: "1000") {
    name
    height(unit: FOOT)
  }
}

// Result
{
  "data": {
    "human": {
      "name": "Luke Skywalker",
      "height": 5.6430448
    }
  }
}

Aliases

  • 별칭도 지정할 수 있음.
// Query
{
  empireHero: hero(episode: EMPIRE) {
    name
  }
  jediHero: hero(episode: JEDI) {
    name
  }
}

// Result
{
  "data": {
    "empireHero": {
      "name": "Luke Skywalker"
    },
    "jediHero": {
      "name": "R2-D2"
    }
  }
}

Fragment

  • 파셜과 같은 느낌으로 반복되는 부분을 별도로 정의할 수 있음.
  • 문법을 보고 있으면 expand라는 느낌을 지울 수가 없다.
// Query
{
  leftComparison: hero(episode: EMPIRE) {
    ...comparisonFields
  }
  rightComparison: hero(episode: JEDI) {
    ...comparisonFields
  }
}

fragment comparisonFields on Character {
  name
  appearsIn
  friends {
    name
  }
}

// Result
{
  "data": {
    "leftComparison": {
      "name": "Luke Skywalker",
      "appearsIn": [
        "NEWHOPE"
      ],
      "friends": [
        {
          "name": "Han Solo"
        }
      ]
    },
    "rightComparison": {
      "name": "R2-D2",
      "appearsIn": [
        "NEWHOPE"
      ],
      "friends": [
        {
          "name": "Luke Skywalker"
        }
      ]
    }
  }
}

Variables

  • 동적으로 변수를 주입할 수 있음
  • $variable과 같은 방식으로 선언, 사용
  • 변수 선언에는 타입을 지정해야함
  • !을 사용해서 조건부인지 필수인지 지정할 수 있음
  • 값을 주입할 때에는 key: value(주로 JSON) 방식으로 처리
// Query
query HeroNameAndFriends($episode: Episode) {
  hero(episode: $episode) {
    name
    friends {
      name
    }
  }
}

// Variables
{
  "episode": "JEDI"
}

// Result
{
  "data": {
    "hero": {
      "name": "R2-D2",
      "friends": [
        {
          "name": "Luke Skywalker"
        }
      ]
    }
  }
}

### Directives

- 변수를 사용해 조건부로 특정 필드를 추가/제거할  있음
- Field, Fragment에서 사용할  있음
- 공식 스펙에서 정의하는 것은 2.
  - `@include(if: Boolean)`
  - `@skip(if: Boolean)`

```js
// Query
query Hero($episode: Episode, $withFriends: Boolean!) {
  hero(episode: $episode) {
    name
    friends @include(if: $withFriends) {
      name
    }
  }
}

// Variables
{
  "episode": "JEDI",
  "withFriends": false
}

Mutations

  • not only fetch, but also post
  • 일반 쿼리와 유사한 방식으로 사용할 수 있음
  • 일반 쿼리는 변경 가능성이 없어서 병렬로 처리하지만, Mutation은 변경 가능성이 있으므로 순차실행
// Query
mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
  createReview(episode: $ep, review: $review) {
    stars
    commentary
  }
}

// Variables
{
  "ep": "JEDI",
  "review": {
    "stars": 5,
    "commentary": "This is a great movie!"
  }
}

// Results
{
  "data": {
    "createReview": {
      "stars": 5,
      "commentary": "This is a great movie!"
    }
  }
}

Inline fragment

  • 특정 타입인 경우에 값을 추가. -> 인터페이스 역할
// Query
query HeroForEpisode($ep: Episode!) {
  hero(episode: $ep) {
    name
    ... on Droid {
      primaryFunction
    }
    ... on Human {
      height
    }
  }
}

Meta field

  • 해당 GraphQL 서비스의 정보를 반환하는 필드
  • __typename
  • __schema
  • __type
# Query
{
  __schema {
    types {
      name
    }
  }
}

// Result
{
  "data": {
    "__schema": {
      "types": [
        {
          "name": "Query"
        },
        // ...
        {
          "name": "__DirectiveLocation"
        }
      ]
    }
  }
}