본문 바로가기

배움의 즐거움/프로그래밍

(8) Graphql-ruby - Introspection

반응형




Introspection


GraphQL 스키마는 스키마의 구조를 보여주는 내장된 introspection system 시스템이 있다. 실제로, 이 introspection 시스템은 GraphQL을 이용하여 요청할 수 있다.

{
  __schema {
    queryType {
      name
    }
  }
}
# Returns:
# {
#   "data": {
#     "__schema": {
#       "queryType": {
#         "name": "Query"
#       }
#     }
#   }
# }

이것은 GraphiQL editor 와 같은 GraphQL 툴을 이용하는데 사용된다. introspection system 기본적인 부분들은 다음과 같다.


  • __schema 는 root-level 필드로 entry point, types 그리고 directives 와 같은 스키마에 대한 정보들을 담고 있다. 
  • __type(name: String!) 역시 root-level 필드로, 주어진 이름에 대한 타입이 있다면 해당 타입에 대한 데이터를 리턴한다. 
  • __typename 는 약간 다르게 동작하는데, 이는 어떠한 selection 에도 추가될 수 있으며, 쿼리된 객체의 타입을 리턴한다.

__typename 예시는 다음과 같다.

{
  user(id: "1") {
    handle
    __typename
  }
}
# Returns:
# {
#   "data": {
#     "user": {
#       "handle": "rmosolgo",
#       "__typename": "User"
#     }
#   }
# }


union과 interface의 경우, __typename 은 현재 객체의 객체 타입을 리턴한다.

{
  search(term: "puppies") {
    title
    __typename
  }
}
# Returns:
# {
#   "data": {
#     "search": [
#       {
#         "title": "Sound of Dogs Barking",
#         "__typename": "AudioClip",
#       },
#       {
#         "title": "Cute puppies playing with a stick",
#         "__typename": "VideoClip",
#       },
#       {
#         "title": "The names of my favorite pets",
#         "__typename": "TextSnippet"
#       },
#     ]
#   }
# }


Customizing Introspection


이것은 실험적인 기능으로써, class-based 스키마에서만 지원한다. class-based 스키마에서 너는 자신만의 introspection 타입을 사용할 수 있다.

# 커스텀 타입을 위한 모듈 이름 생성
module Introspection
  # 
end

class MySchema < GraphQL::Schema
  # ...
  # 그리고 해당 모듈을 introspection으로 전달
  introspection Introspection
end

참고로 off-the-shelf 툴은 커스텀 introspection 필드를 지원하지 않을 수도 있으므로 현존하는 툴을 수정하거나, 자신만의 툴을 만들어야 할 수 도 있다.


Custom Introspection Types


Custom class name

GraphQL type

Built-in class name

SchemaType__Schema

GraphQL::Introspection::SchemaType

TypeType__Type

GraphQL::Introspection::TypeType

DirectiveType__Directive

GraphQL::Introspection::DirectiveType

DirectiveLocationType__DirectiveLocation

GraphQL::Introspection::DirectiveLocationEnum

EnumValueType__EnumValue

GraphQL::Introspection::EnumValueType

FieldType__Field

GraphQL::Introspection::FieldType

InputValueType__InputValue

GraphQL::Introspection::InputValueType

TypeKindType__TypeKind

GraphQL::Introspection::TypeKindEnum


Extending a Built-in Type

위와 같은 내장 타입은 아래와 같이 확장 될 수 있다.

module Introspection
  class SchemaType < GraphQL::Introspection::SchemaType
    # ...
  end
end


클래스 안에서는 다음과 같은 것들을 할 수 있다.

  • field(...) 를 호출함으로써 새로운 필드 추가
  • field(...) 를 호출함으로써 새롭게 필드 재구성
  • 새로운 메서드 정의를 이용하여 필드 구현
  • description(...) 을 호출함으로써 새롭게 descriptions 제공 by calling


Introspection Entry Points


GraphQL 스펙은 은 두가지 엔트리 포인트를 설명한다.

  • __schema 스키마에 대한 정보 리턴 (__Schema 타입으로)
  • __type(name:) : 해당 이름으로 찾아진 데이터 리턴(__Type 타입으로)

introspection 네임스페이스 내에 커스텀 EntryPoints 클래스를 만들어서 직접 해당 필드들을 재구현할 수 있다.

module Introspection
  class EntryPoints < GraphQL::Introspection::EntryPoints
    # ...
  end
end

This class an object type definition, so you can override fields or add new ones here. They’ll be available on the root query object, but ignored in introspection (just like __schema an__type). ?


Dynamic Fields

__typename 은 현재 GraphQL 타입의 이름을 리턴한다.

아래처럼 커스텀 DynamicFields 을 생성함으로써 필드를 추가할 수 있다. (또는  __typename 을 오버라이드할 수 있다)

module Introspection
  class DynamicFields < GraphQL::Introspection::DynamicFields
    # ...
  end
end

Any fields defined there will be available in any selection, but ignored in introspection (just like __typename). ?


* 해당 글은 번역기 돌리다가 크롬 번역기 말도 안되는 해석에 지친 본인이 나중에 참고할 의도로 대충대충 발로 해석한 것이니 참고용으로만 사용하시길 바랍니다.

* 출처: http://graphql-ruby.org/schema/introspection.html



반응형

'배움의 즐거움 > 프로그래밍' 카테고리의 다른 글

(10) Graphql-ruby - 스키마 테스팅  (0) 2018.12.31
(9) Graphql-ruby - Generators  (0) 2018.12.31
(7) Graphql-ruby - 스키마 정의  (0) 2018.12.31
(6) GraphQL - 인트로스펙션  (0) 2018.12.31
(5) GraphQL - 실행  (0) 2018.12.31