GraphQL - Docs를 통한 정리(쿼리)

Jihun Kim·2022년 4월 20일
0

GraphQL

목록 보기
2/16
post-thumbnail

이 글은 GraphQL Docs를 읽고 정리한 것입니다.

쿼리

필드

  • GraphQL은 서버에서 클라이언트가 요청하는 필드를 정확히 알고 있기 때문에 쿼리와 결과가 정확히 동일한 형태이다.
  • GraphQL 쿼리는 연관된 객체와 필드를 탐색할 수 있다.
    - 따라서, 한 번의 요청으로 많은 데이터를 가져올 수 있다.
  • 스키마를 기반으로 예상되는 결과를 알 수 있다
    - 즉, 아래의 예시의 경우 book은 배열을 반환하는데 이는 스키마를 기반으로 예상된 결과이다.

쿼리

 {
	book {
 		title   
      }
   }

실행 결과

 {
   "data": {
       "book": [
       	{
             "title": "Harry Potter"
       	},
         {
         	"title": "The Lord of the Rings"
         }
       ]
    }
 }

인자

  • GraphQL에서는 모든 필드와 중첩된 객체가 인자를 가질 수 있다.
    - REST API는 요청에 query parameter와 URL 세그먼트 같이 단일 인자를 전달하기 때문에 여러 번의 API fetch를 거쳐야 하지만, GraphQL은 서버에서 데이터 변환을 한 번만 구현할 수도 있다.
  • GraphQL은 이미 기본 타입을 제공하고 있지만 GraphQL 서버는 직접 커스텀 타입을 선언할 수 있다.

쿼리

 {
	book(id: 100) {
 		title
         author(name: family)
      }
   }

실행 결과

 {
   "data": {
       "book": {
             "title": "Harry Potter",
             "author": "Rowling"
       	}
    }
 }

별칭

  • 결과 객체 필드는 쿼리의 필드명과 일치한다. 하지만 인자는 같은 필드에 대해 다른 값을 줄 수 있다.
  • 이처럼 같은 필드에 대해 다른 인자를 줄 경우 필드의 결과를 원하는 것으로 바꿀 수 있는데 이것이 별칭이다.

쿼리

 {
	earlyPotter: book(date: early){
 		title
      }
     latePotter: book(date: late){
 		title
      }
   }

실행 결과

 {
   "data": {
   	  "earlyPotter": {
           "title": "Harry Potter and the Sorcerer's Stone"
       },
       "latePotter": {
            "title": "Harry Potter and the Deathly Hallows"
       	}
    }
 }

프래그먼트

  • 프래그먼트는 중복되는 쿼리에 사용할 수 있는 재사용 가능한 단위이다.
    - 프래그먼트를 이용해 필드셋을 구성한 후 필요한 쿼리에 포함시킬 수 있다.
  • 복잡한 데이터 요구 사항을 작은 단위로 분할하기 위해 사용한다.
  • 추가적으로, 쿼리나 뮤테이션에 선언된 변수는 프래그먼트에 접근이 가능하다고 한다(이에 대한 예시는 따로 추가하지 않았다).

프래그먼트 예시 쿼리는 기존보다 복잡해서 독스의 예시를 그대로 가져왔다.

쿼리

 {
   leftComparison: hero(episode: EMPIRE) {
     ...comparisonFields
   }
   rightComparison: hero(episode: JEDI) {
     ...comparisonFields
   }
 }
 
 fragment comparisonFields on Character {
   name
   appearsIn
   friends {
     name
   }
 }

실행 결과

 {
"data": {
 "leftComparison": {
   "name": "Luke Skywalker",
   "appearsIn": [
     "NEWHOPE",
     "EMPIRE",
     "JEDI"
   ],
   "friends": [
     {
       "name": "Han Solo"
     },
     {
       "name": "Leia Organa"
     },
     {
       "name": "C-3PO"
     },
     {
       "name": "R2-D2"
     }
   ]
 },
 "rightComparison": {
   "name": "R2-D2",
   "appearsIn": [
     "NEWHOPE",
     "EMPIRE",
     "JEDI"
   ],
   "friends": [
     {
       "name": "Luke Skywalker"
     },
     {
       "name": "Han Solo"
     },
     {
       "name": "Leia Organa"
     }
   ]
 }
}
}

작업 이름

  • 위의 예시들처럼 query 키워드와 query 이름을 생략한 단축 문법을 사용하는 것도 좋지만 실제로는 작업 이름을 정해 코드를 헷갈리지 않게 사용하는 것이 좋다.
  • 작업 타입은 query, mutation, subscription 중 하나를 선택할 수 있다.
  • 작업 이름을 이용하면 디버깅 하거나 서버에서 로깅할 때 유용하다고 한다.

쿼리

query HeroNameAndFriends {
  hero {
    name
    friends {
      name
    }
  }
}

실행 결과

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

변수

  • GraphQL은 동적 인자를 쿼리 문자열에 직접 전달하지 않고 이를 변수를 이용해 전달하도록 한다.
    - 이 방법은 쿼리의 어떤 인자가 동적인 지를 나타내는 좋은 방법이기도 하다.
  • $variableName을 쿼리에서 받는 변수로 선언해 variableName: value로 전달하면 된다.
    - 타입 선언 다음 기본값을 명시해 기본값을 할당할 수도 있다.
    - 아래 예시의 경우 ($episode: Episode = "JEDI")로 기본값을 명시하면 된다.

아래 예시에서 Episode는 타입을 의미한다.
쿼리

query HeroNameAndFriends($episode: Episode) {
   hero(episode: $episode) {
     name
    friends {
      name
    }
  }
}

// variables
{
  "episode": "JEDI"
}

실행 결과

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

지시어

  • 지시어는 필드나 프래그먼트 안에 추가할 수 있다.
  • 지시어를 이용하면 서버가 원하는 방식으로 쿼리 실행을 하도록 만들 수 있다.
  • GraphQL에서 사용되는 지시어는 아래의 두 가지이다.
    - @include(if: $variableName): 인자가 true 인 경우에만 이 필드를 결과에 포함한다.
    - @skip(if: $variableName) 인자가 true 이면 이 필드를 건너뛴다.

여기서 $variableName은 type이 Boolean이어야 한다. 아래 예시에서 확인할 수 있다.
!은 필수로 포함되어야 할 때 사용한다.

쿼리

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

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

실행 결과

{
  "data": {
    "hero": {
      "name": "R2-D2"
    }
  }
}
    
profile
쿄쿄

0개의 댓글