현인
GraphQL 학습 - 6장 스키마 확인(Introspection) 본문
GraphQL 스키마가 지원하는 쿼리에 대한 정보를 요청하는 것은 매우 유용한 기능이다. GraphQL은 Introspection(이하 스키마 확인) 시스템을 통해 이를 효과적으로 수행할 수 있게 해준다.
스타워즈 예제에서 사용된 starWarsIntrospection-test.ts 파일은 스키마 확인 시스템의 실용성을 잘 보여준다. 이 파일에는 다양한 스키마 확인 쿼리가 포함되어 있어, 참조 구현의 스키마 확인 시스템을 효과적으로 테스트할 수 있다.
타입 시스템을 직접 설계했다면 사용 가능한 타입들을 알고 있겠지만, 그렇지 않은 경우에도 GraphQL의 강력한 기능을 활용할 수 있다. Query의 루트 타입에 항상 존재하는 __schema 필드를 쿼리하면, 필요한 모든 정보를 손쉽게 얻을 수 있다. 이제 이 유용한 기능을 사용하여 사용 가능한 타입들에 대해 알아보자.
{
__schema {
types {
name
}
}
}
{
"data": {
"__schema": {
"types": [
{
"name": "Query"
},
{
"name": "String"
},
{
"name": "ID"
},
{
"name": "Mutation"
},
{
"name": "Episode"
},
{
"name": "Character"
},
{
"name": "Int"
},
{
"name": "LengthUnit"
},
{
"name": "Human"
},
{
"name": "Float"
},
{
"name": "Droid"
},
{
"name": "FriendsConnection"
},
{
"name": "FriendsEdge"
},
{
"name": "PageInfo"
},
{
"name": "Boolean"
},
{
"name": "Review"
},
{
"name": "ReviewInput"
},
{
"name": "Starship"
},
{
"name": "SearchResult"
},
{
"name": "__Schema"
},
{
"name": "__Type"
},
{
"name": "__TypeKind"
},
{
"name": "__Field"
},
{
"name": "__InputValue"
},
{
"name": "__EnumValue"
},
{
"name": "__Directive"
},
{
"name": "__DirectiveLocation"
}
]
}
}
}
많은 타입을 확인할 수 있는데, 그룹으로 나눠보면
- Query, Character, Human, Episode, Droid - 타입 시스템에서 직접 정의한 것들
- String, Boolean - 타입 시스템에서 제공하는 기본적인 스칼라 타입
- __Schema, __Type, __TypeKind, __Field, __InputValue, __EnumValue, __Directive - 이들은 모두 더블 언더스코어로 시작하는데, 이는 스키마 확인 시스템의 일부라는 것을 나타냄
이제, 어떤 쿼리가 사용 가능한지 탐색하기 위한 좋은 출발점을 찾아보자. 타입 시스템을 설계할 때, 모든 쿼리가 시작할 타입을 지정했으므로 스키마 확인 시스템에 그 정보를 물어보자.
{
__schema {
queryType {
name
}
}
}
{
"data": {
"__schema": {
"queryType": {
"name": "Query"
}
}
}
}
이는 타입 시스템 섹션에서 배운 것과 일치한다. Query 타입이 시작할 곳이다. 여기서 이름은 단지 관습일 뿐이다. Query 타입에 다른 이름을 쓸 수도 있고, 쿼리의 시작 타입으로 지정했다면, 똑같이 반환되었을 것이다. 하지만, Query라는 이름은 일반적이 관습이다.
특정 타입을 검사하는 것이 유용한 경우가 많다. Droid 타입을 살펴보자.
{
__type(name: "Droid") {
name
}
}
{
"data": {
"__type": {
"name": "Droid"
}
}
}
Droid에 대해 더 많이 알고 싶다면? 예를 들어, 인터페이스인지 객체인지 알고 싶다면?
{
__type(name: "Droid") {
name
kind
}
}
{
"data": {
"__type": {
"name": "Droid",
"kind": "OBJECT"
}
}
}
kind는 __TypeKind 열거형(enum)을 반환했는데, 해당 값은 OBJECT다. 대신 Character에 의해 요청하면 인터페이스라는 것을 알 수 있다.
{
__type(name: "Character") {
name
kind
}
}
{
"data": {
"__type": {
"name": "Character",
"kind": "INTERFACE"
}
}
}
어떤 객체가 어떤 필드를 사용할 수 있는지 아는 것이 유용하기 때문에, Droid를 스키마 확인 시스템에 요청해보자.
{
__type(name: "Droid") {
name
fields {
name
type {
name
kind
}
}
}
}
{
"data": {
"__type": {
"name": "Droid",
"fields": [
{
"name": "id",
"type": {
"name": null,
"kind": "NON_NULL"
}
},
{
"name": "name",
"type": {
"name": null,
"kind": "NON_NULL"
}
},
{
"name": "friends",
"type": {
"name": null,
"kind": "LIST"
}
},
{
"name": "friendsConnection",
"type": {
"name": null,
"kind": "NON_NULL"
}
},
{
"name": "appearsIn",
"type": {
"name": null,
"kind": "NON_NULL"
}
},
{
"name": "primaryFunction",
"type": {
"name": "String",
"kind": "SCALAR"
}
}
]
}
}
}
이 값들이 Droid에서 정의한 필드들이다.
id는 약간 이상해 보인다. 타입에 대한 이름이 없다. 종류가 NON_NULL인 wrapper 타입이기 때문이다. 필드의 타입에서 ofType을 쿼리하면, 이 Id가 non-null임을 알려주는 ID 타입을 반환할 것이다.
비슷하게, friends와 appearIn 둘 다 LIST wrapper 타입이기 때문에 이름이 없다. 이 타입에 대해 ofType을 쿼리 할 수 있다. 그러면 이 list가 어떤 list 인지 알 수 있다.
{
__type(name: "Droid") {
name
fields {
name
type {
name
kind
ofType {
name
kind
}
}
}
}
}
{
"data": {
"__type": {
"name": "Droid",
"fields": [
{
"name": "id",
"type": {
"name": null,
"kind": "NON_NULL",
"ofType": {
"name": "ID",
"kind": "SCALAR"
}
}
},
{
"name": "name",
"type": {
"name": null,
"kind": "NON_NULL",
"ofType": {
"name": "String",
"kind": "SCALAR"
}
}
},
{
"name": "friends",
"type": {
"name": null,
"kind": "LIST",
"ofType": {
"name": "Character",
"kind": "INTERFACE"
}
}
},
{
"name": "friendsConnection",
"type": {
"name": null,
"kind": "NON_NULL",
"ofType": {
"name": "FriendsConnection",
"kind": "OBJECT"
}
}
},
{
"name": "appearsIn",
"type": {
"name": null,
"kind": "NON_NULL",
"ofType": {
"name": null,
"kind": "LIST"
}
}
},
{
"name": "primaryFunction",
"type": {
"name": "String",
"kind": "SCALAR",
"ofType": null
}
}
]
}
}
}
이제 마지막으로 툴을 만들때 특히 유용한 스키마 확인 시스템의 기능을 보자. 시스템에 문서를 요청해보면
{
__type(name: "Droid") {
name
description
}
}
{
"data": {
"__type": {
"name": "Droid",
"description": "An autonomous mechanical character in the Star Wars universe"
}
}
}
이렇게 스키마 확인 기능을 사용하여 타입 시스템에 대한 문서에 접근 할 수 있고 문서 탐색기나 풍부한 IDE 환경을 만들수도 있다.
이것은 그저 스키마 확인 시스템의 극히 일부이다. enum 값, 타입이 구현하는 인터페이스 등을 쿼리 할 수도 있다. 심지어 스키마 확인 시스템 자체에도 이 시스템을 사용 할 수 있다. 이 명세에 대한 자세한 내용은 introspection 섹션을 참조하자. GraphQL.js에 Introspection 파일에는 이 사양을 준수하는 GraphQL 쿼리 스키마 확인 시스템을 구현하는 코드가 있다.
출처
https://graphql.org/learn/introspection/
Introspection | GraphQL
Copyright © 2024 The GraphQL Foundation. All rights reserved. For web site terms of use, trademark policy and general project policies please see https://lfprojects.org
graphql.org
https://graphql-kr.github.io/learn/introspection/
GraphQL: API를 위한 쿼리 언어
GraphQL은 API에 있는 데이터에 대한 완벽하고 이해하기 쉬운 설명을 제공하고 클라이언트에게 필요한 것을 정확하게 요청할 수 있는 기능을 제공하며 시간이 지남에 따라 API를 쉽게 진화시키고
graphql-kr.github.io
'기술 학습 > GraphQL' 카테고리의 다른 글
GraphQL 학습 - 5장 실행(Execution) (1) | 2024.11.14 |
---|---|
GraphQL 학습 - 4장 유효성 검증(Validation) (0) | 2024.11.14 |
GraphQL 학습 - 3장 스키마(Schema) & 타입(Type) (3) | 2024.11.14 |
GraphQL 학습 - 2장 쿼리(Query) & 뮤테이션(Mutation) (1) | 2024.11.14 |
GraphQL 학습 - 1장 GraphQL 소개 (0) | 2024.11.14 |