graphql

x·2022년 9월 20일
0

client에서 gql 언어로 query 또는 mutation을 request하면 server는 resolve해서 json으로 response한다.

resolve
프론트엔드에서 쿼리를 날리면 graphql server에서는 rootquery에서 field를 찾고 resolve 메서드를 통해 입력된 args에 맞는 값을 찾는다. resolve 메서드는 DB에서 데이터를 얻어오기 위한 것이다. 실제 데이터를 반환하는 역할

type relations
RDB처럼 타입에 관계 지정
BookType, AuthorType이 있다고 하면 BookType의 author field에 AuthorType을 지정. resolve 메서드는 authors DB에서 id가 book의 author id인 것을 찾고 반환하도록 함

fragment
반복되는 필드를 fragment라는 재사용 가능한 단위로 만들어 쿼리에 사용할 수 있다.

지시어
변수를 써서 쿼리의 구조와 형태를 동적으로 변경할 수 있음
지시어는 필드나 프래그먼트 안에 삽입될 수 있음
@include(if: Boolean): 인자가 true 인 경우에만 이 필드를 결과에 포함합니다.
@skip(if: Boolean) 인자가 true 이면 이 필드를 건너뜁니다.

query Hero($episode: Episode, $withFriends: Boolean!, $skp:Boolean!) {
  hero(episode: $episode) {
    name
    friends @include(if: $withFriends) {
      name
    }
    friendsConnection @skip(if:$skp){
     totalCount 
      edges{
        node{
          name
        }
      }
    }
  }
}
{
  "episode": "JEDI",
  "withFriends": true,
  "skp": false
}

뮤테이션

mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
  createReview(episode: $ep, review: $review) {
    stars
    commentary
  }
}

createReview 필드가 새로 생성된 리뷰의 stars 와 commentary 필드를 반환

스키마&타입
타입 시스템

{
  hero {
    name
    appearsIn
  }
}

root 객체로 시작합니다.
hero 필드를 선택합니다.
hero 에 의해 반환된 객체에 대해 name 과 appearIn 필드를 선택합니다.

스키마가 필요한 이유
선택할 수 있는 필드, 반환할 객체 종류, 하위 객체에서 사용할 수 있는 필드를 명시하기 위함

모든 GraphQL 서비스는 해당 서비스에서 쿼리 가능한 데이터들을 완벽하게 설명하는 타입들을 정의하고, 쿼리가 들어오면 해당 스키마에 대해 유효성이 검사된 후 실행됩니다.

스칼라 타입
graphQL 객체 타입은 이름과 필드를 가지지만 어떤 시점에서 필드는 구체적인 데이터로 해석되어야 함. 쿼리의 끝을 나타냄

{
  hero {
    name
    appearsIn
  }
}

name, appearsIn은 스칼라 타입으로 해석됨
Int: 부호가 있는 32비트 정수.
Float: 부호가 있는 부동소수점 값.
String: UTF-8 문자열.
Boolean: true 또는 false.
ID: ID 스칼라 타입은 객체를 다시 요청하거나 캐시의 키로써 자주 사용되는 고유 식별자를 나타냅니다. ID 타입은 String 과 같은 방법으로 직렬화되지만, ID 로 정의하는 것은 사람이 읽을 수 있도록 하는 의도가 아니라는 것을 의미합니다.

열거형 타입 enums
특정 값들로 제한되는 특별한 종류의 스칼라
타입의 인자가 허용된 값 중 하나임을 검증
필드가 항상 값의 열거형 집합 중 하나가 될 것임을 타입 시스템을 통해 의사소통
열거형 타입 정의

enum Episode {
  NEWHOPE
  EMPIRE
  JEDI
}

스키마에서 Episode 타입을 사용할 때마다 정확히 저 3개 중 하나일 것이다.

타입에 따라 필드를 달리 가져와야 할 때는 프래그먼트를 사용하면 되는데 재사용하지 않는 경우 이름이 있는 프래그먼트 대신 인라인 프래그먼트를 사용하면 된다.

실행
타입의 각 필드는 graphQL 서버 개발자가 만든 resolver 함수에 의해 실행됨. 필드가 실행되면 해당 resolver가 호출되어 다음 값을 생성함
필드가 문자열이나 숫자 같은 스칼라 값을 반환하면 실행 완료. 필드가 객체를 반환하면 그 안의 필드가 스칼라 값에 도달할 때까지 반복됨

스키마 확인

{
  __schema {
    types {
      name
    }
  }
}

위 코드를 요청해서 schema를 확인할 수 있다.
__가 붙은 타입은 스키마 확인 시스템의 일부다.

subscribe (webhook, 사용자 정의 콜백)
구독 중인 이벤트가 발생했을 때 서버에서 작업을 함

https://graphql-kr.github.io/learn/queries/#


graphql로 쿼리 실행해보기
jupyter notebook에서 실행함

import graphene
import json
from datetime import datetime 

# object type 정의
class Board(graphene.ObjectType):
    bno = graphene.ID()
    btitle = graphene.String()
    bdate = graphene.DateTime()

# query 정의
class Query(graphene.ObjectType):
    boards = graphene.List(Board, first=graphene.Int())
    
    # boards 필드에 대한 query 요청이 들어오면 응답할 값 resolve
    def resolve_boards(self, info, first):
        return [
            Board(btitle='Title1', bdate=datetime.now()),
            Board(btitle='Title2', bdate=datetime.now()),
            Board(btitle='Title3', bdate=datetime.now()),
            Board(btitle='Title4', bdate=datetime.now())
        ][:first]

schema = graphene.Schema(query=Query)

result = schema.execute(
    """
    {
        boards (first:2) {
            btitle
            bdate
        }
    }
    """
)

print(json.dumps(result.data, indent=2))

0개의 댓글