테스트 사이트 - 개발 중인 베타 버전입니다

#3-1 GraphQL - Introspection

· 8년 전 · 1803

Producing the result

각 필드가 분석될 때 결과 값은 필드 이름 (또는 별칭)을 키로 사용하고 확인 된 값을 값으로 사용하여 키 -값 맵에 배치됩니다.이 방법은 쿼리의 맨 아래 리프 필드에서부터 계속됩니다. 루트 쿼리 유형의 원래 필드까지 집합 적으로 이것들은 원본 쿼리를 미러링하는 구조를 만들어서 요청한 클라이언트에 (일반적으로 JSON으로) 보낼 수 있습니다. 

 

원래의 쿼리를 마지막으로 살펴보고 이러한 모든 해석 함수가 결과를 어떻게 생성하는지 살펴 보겠습니다. 

{

  human(id: 1002) {

    name

    appearsIn

    starships {

      name

    }

  }

}

{

  "data": {

    "human": {

      "name": "Han Solo",

      "appearsIn": [

        "NEWHOPE",

        "EMPIRE",

        "JEDI"

      ],

      "starships": [

        {

          "name": "Millenium Falcon"

        },

        {

          "name": "Imperial shuttle"

        }

      ]

    }

  }

}

 

Introspection

GraphQL 스키마에서 지원하는 쿼리에 대한 정보를 요청하는 것이 유용합니다. GraphQL은 우리가 내성(introspection) 시스템을 사용하여 그렇게 할 수있게 해줍니다!

 

Star Wars 예제의 경우 starWarsIntrospection-test.js 파일에는 인트로스펙션 시스템을 보여주는 여러 가지 쿼리가 포함되어 있으며 참조 구현의 인트로스펙션 시스템을 실행하기 위해 실행할 수 있는 테스트 파일입니다.

 

우리는 타입 시스템을 설계 했으므로 사용할 수 있는 타입이 무엇인지 알았지만 그렇지 않다면 __schema 필드를 쿼리하여 GraphQL에 쿼리의 루트 유형에서 항상 사용할 수 있는지 물어볼 수 있습니다. 지금 당장 사용 가능한 유형을 묻습니다.

{

  __schema {

    types {

      name

    }

  }

}

{

  "data": {

    "__schema": {

      "types": [

        {

          "name": "Query"

        },

        {

          "name": "Episode"

        },

        {

          "name": "Character"

        },

        {

          "name": "ID"

        },

        {

          "name": "String"

        },

        {

          "name": "Int"

        },

        {

          "name": "FriendsConnection"

        },

        {

          "name": "FriendsEdge"

        },

        {

          "name": "PageInfo"

        },

        {

          "name": "Boolean"

        },

        {

          "name": "Review"

        },

        {

          "name": "SearchResult"

        },

        {

          "name": "Human"

        },

        {

          "name": "LengthUnit"

        },

        {

          "name": "Float"

        },

        {

          "name": "Starship"

        },

        {

          "name": "Droid"

        },

        {

          "name": "Mutation"

        },

        {

          "name": "ReviewInput"

        },

        {

          "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 열거 형을 반환하며 그 중 하나의 값은 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 유형이 null이 아닌 ID임을 알 수 있습니다.

 

비슷하게, friends와 appearIn은 모두 LIST 래퍼 유형이므로 이름이 없습니다. 우리는 이러한 유형에 대해 ofType을 쿼리 할 수 있습니다. 그러면 이러한 유형이 무엇인지 알려줍니다.

{
  __type(name: "Droid") {
    name
    fields {
      name
      type {
        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

          }

        }

      ]

    }

  }

}

툴링(tooling)에 특히 유용한 인트로스펙션 시스템의 기능을 끝내자. 시스템에 문서를 요청하십시오! 

{

  __type(name: "Droid") {

    name

    description

  }

}

{

  "data": {

    "__type": {

      "name": "Droid",

      "description": "An autonomous mechanical character in the Star Wars universe"

    }

  }

}

따라서 우리는 인트로스펙션을 사용하여 유형 시스템에 대한 문서에 액세스하고 문서 브라우저 또는 풍부한 IDE 경험을 만들 수 있습니다.

 

이것은 단지 인트로스펙션 시스템의 표면을 긁었다; enum 값, 유형이 구현하는 인터페이스 등을 쿼리 할 수 있습니다. 우리는 심지어 인트로스펙션 시스템 자체에 대해 인트로스펙트할 수 있습니다. 이 사양은 "인트로스펙션" 섹션에서 이 항목에 대해 더 자세히 설명하고 GraphQL.js의 내부 파일에는 사양을 준수하는 GraphQL 쿼리 인트로스펙션 시스템을 구현하는 코드가 들어 있습니다.

 


댓글 작성

댓글을 작성하시려면 로그인이 필요합니다.

로그인하기

게시글 목록

번호 제목
1623
1619
1618
1616
1615
1614
1613
1612
1611
1606
1602
1598
1595
1594
1586
1582
1579
1576
1571
1561
1560
1557
1552
1551
1541
1539
1538
1536
1532
1530