긴 쿼리를 작성하지 않고 모든 GraphQL 유형 필드를 쿼리하는 방법은 무엇입니까?


130

GraphQL 유형이 있고 많은 필드를 포함한다고 가정합니다. 모든 필드의 이름을 포함하는 긴 쿼리를 작성하지 않고 모든 필드를 쿼리하는 방법은 무엇입니까?

예를 들어, 다음 필드가있는 경우 :

 public function fields()
    {
        return [
            'id' => [
                'type' => Type::nonNull(Type::string()),
                'description' => 'The id of the user'
            ],
            'username' => [
                'type' => Type::string(),
                'description' => 'The email of user'
            ], 
             'count' => [
                'type' => Type::int(),
                'description' => 'login count for the user'
            ]

        ];
    }

모든 필드를 쿼리하려면 일반적으로 쿼리는 다음과 같습니다.

FetchUsers{users(id:"2"){id,username,count}}

그러나 다음과 같이 모든 필드를 작성하지 않고도 동일한 결과를 얻을 수있는 방법을 원합니다.

FetchUsers{users(id:"2"){*}}
//or
FetchUsers{users(id:"2")}

GraphQL에서 이것을 수행하는 방법이 있습니까?

내가 사용하고 Folkloreatelier / laravel-graphql 라이브러리를.


4
GraphQL이 설계 상 지원하지 않는 작업을 수행하는 방법을 묻는 것입니다.
트래비스 웹의

12
40 개의 필드를 입력하고 오타가 발생하지 않기를 바랍니다. :)
Ska

32
와, 저는 GraphQL에서 막 시작했습니다. 이것은 심각한 WTF입니다.
user949300

1
지원되지 않는다고 가정 해 보겠습니다. Student 및 Class 개체가 있고, 학생은 자신이 참석하는 모든 수업을 나열하는 "classes"필드가 있고, 해당 클래스에는 해당 수업에 참석하는 모든 학생을 나열하는 "students"필드가 있습니다. 그것은 순환 구조입니다. 이제 모든 필드를 가진 모든 학생을 요청하면 반환 된 모든 클래스 필드도 포함됩니까? 그리고 그 수업에는 학생들이 있습니다. 그들의 분야도 포함됩니까? 그리고 학생들은 수업을 ...
Buksy

나는이 질문을했고, 그것이 무엇을 끌어낼 수 있는지 볼 수 있도록했다. GraphQL 클라이언트의 많은 (예를 들어 GraphiQL는 참조 gatsbyjs.org/docs/running-queries-with-graphiql을 즉 "모든 것을 얻을하고자 뒤에 이유가 있다면, 당신이 당길 수있는 당신을 제공하기 위해 자기 반성을 사용하는 스키마 탐색기가) ".
James

답변:


120

불행히도 당신이 원하는 것은 불가능합니다. GraphQL에서는 쿼리에서 반환 할 필드를 명시 적으로 지정해야합니다.


5
좋아, 백엔드에서 알 수없는 형식의 개체를 요청하면 프록시하거나 다시 보내야합니까?
meandre

19
@meandre, graphql의 전체 아이디어는 "알려지지 않은 형태"와 같은 것이 없다는 것입니다.
s.meijer

2
@meandre, 아래 내 대답이 유용 할 수 있습니까?
Tyrone Wilson

대부분의 API 쿼리 언어와 프로토콜? @meandre의 전체 생각이 아니다
클리스터스

흥미 롭습니다. graphql을 사용할 때 정말 다른 사고 방식입니다
andy mccullough

91

예, introspection을 사용하여 수행 할 수 있습니다. . GraphQL 쿼리를 ( UserType 유형에 대해 )

{
   __type(name:"UserType") {
      fields {
         name
         description
      }  
   }
}

(실제 필드 이름은 실제 스키마 / 유형 정의에 따라 다름)와 같은 응답을 받게됩니다.

{
  "data": {
    "__type": {
      "fields": [
        {
          "name": "id",
          "description": ""
        },
        {
          "name": "username",
          "description": "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only."
        },
        {
          "name": "firstName",
          "description": ""
        },
        {
          "name": "lastName",
          "description": ""
        },
        {
         "name": "email",
          "description": ""
        },
        ( etc. etc. ...)
      ]
    }
  }
}

그런 다음 클라이언트에서이 필드 목록을 읽고 두 번째 GraphQL 쿼리를 동적으로 빌드하여 이러한 모든 필드를 가져올 수 있습니다.

이는 필드를 가져 오려는 유형의 이름을 아는 것에 달려 있습니다. 유형을 모르는 경우 다음과 같은 인트로 스펙 션을 사용하여 모든 유형과 필드를 함께 가져올 수 있습니다.

{
  __schema {
    types {
      name
      fields {
        name
        description
      }
    }
  }
}

참고 : 이것은 유선 GraphQL 데이터입니다. 실제 클라이언트로 읽고 쓰는 방법을 스스로 알아낼 수 있습니다. graphQL javascript 라이브러리는 이미 일부 용량에서 introspection을 사용할 수 있습니다. 예를 들어 apollo codegen 명령은 introspection을 사용하여 유형을 생성합니다.


재귀 유형에 대한 관심을 표현해야 할 것 같습니다. 나무 아래로 내려가 자신을 포함하는 유형 (목록, 단일 또는 기타 ..)에 부딪혔다면 무한 재귀를 할 수 있습니다.
Milos Grujic

이 특정 쿼리에 대한 내 경험에서는 실제로 발생하지 않습니다. 쿼리 자체가 해상도 깊이를 정의합니다.
Mark Chackerian

위의 답변은 쿼리에서 사용할 수있는 필드 유형 만 쿼리 할 수 ​​있도록합니다. 원래 질문의 내용 인 모든 개체 필드 "값"을 반환하지는 않습니다.
quantdaddy

4
대답에 따라 첫 번째 쿼리의 결과를 기반으로 두 번째 쿼리를 동적으로 작성해야합니다. 독자를위한 연습으로 남겨 두었습니다.
Mark Chackerian

39

이 작업을 수행하는 유일한 방법은 재사용 가능한 조각을 사용하는 것입니다.

fragment UserFragment on Users {
    id
    username
    count
} 

FetchUsers {
    users(id: "2") {
        ...UserFragment
    }
}

19
내가 그렇게했다면 여전히 각 필드 이름을 "최소한 조각에"써야합니다. 내가 피 하려던 것을 마녀로 삼아야합니다. GraphQL이 우리를 명시 적으로 만들도록하는 것 같습니다.
BlackSigma 2015

이것을 POSTMan 쿼리에 추가하는 방법은 무엇입니까? 또는 jquery / UI 프레임 워크를 사용하여 문자열 화 된 JSON을 만듭니다. 이 graphiQL은 실제 개발 목적으로는 쓸모가 없어 보입니다.
mfaisalhyder

이것은 재사용 목적으로 만 사용됩니다.
Henok Tesfaye

@BlackSigma GraphQL 문서를 고려하면 이것이 최선의 답변으로 받아 들여 져야합니다
JP 벤츄라을

4
@JPVentura : 친구가 아닙니다. 개념과 응용 프로그램 모두에서 재사용 성과 와일드 카드 사이에는 차이가 있습니다. 조각의 목적은 "GraphQL에는 조각이라고하는 재사용 가능한 단위가 포함되어 있습니다."라는 문서에서 분명합니다. 조각을 사용하는 것은 유용하지만 질문에 대한 답은 아닙니다.
BlackSigma

11

Google Places API에서 데이터베이스로 직렬화 한 위치 데이터를로드해야 할 때 이와 동일한 문제에 직면했습니다. 일반적으로 맵과 함께 작동하도록 전체를 원하지만 매번 모든 필드를 지정할 필요는 없었습니다.

저는 Ruby에서 일하고 있었기 때문에 PHP 구현을 제공 할 수 없지만 원칙은 동일해야합니다.

리터럴 JSON 개체 만 반환하는 JSON이라는 사용자 지정 스칼라 유형을 정의했습니다.

루비 구현은 이와 같았습니다 (graphql-ruby 사용).

module Graph
  module Types
    JsonType = GraphQL::ScalarType.define do
      name "JSON"
      coerce_input -> (x) { x }
      coerce_result -> (x) { x }
    end
  end
end

그런 다음 객체에 사용했습니다.

field :location, Types::JsonType

나는 이것을 매우 드물게 사용하고, 항상 전체 JSON 객체가 필요하다는 것을 아는 곳에서만 사용합니다 (내 경우에서했던 것처럼). 그렇지 않으면 더 일반적으로 말하자면 GraphQL의 객체를 무너 뜨리는 것입니다.


1
이것이 바로 제가 필요한 것입니다. 감사합니다. 내 사용 사례는 시스템 전체에 사용자가 번역 할 수있는 문자열이 있으며 db와 같이 json으로 저장됩니다 {"en": "Hello", "es": "Hola"}. 그리고 각 사용자가 사용 사례에 따라 고유 한 언어 하위 집합을 구현할 수 있으므로 UI가 가능한 모든 하위 집합을 쿼리하는 것은 의미가 없습니다. 귀하의 예는 완벽하게 작동합니다.
Luke Ehresman

2

GraphQL 쿼리 형식 은 다음을 허용하도록 설계되었습니다.

  1. 쿼리와 결과 모양이 모두 똑같습니다. 합니다.
  2. 서버는 요청 된 필드를 정확히 알고 있으므로 클라이언트 필수 데이터 다운로드 합니다 .

그러나 GraphQL 문서 에 따르면 선택 세트를 더 재사용하기 위해 조각 을 만들 수 있습니다 .

# Only most used selection properties

fragment UserDetails on User {
    id,
    username
} 

그런 다음 다음을 통해 모든 사용자 세부 정보를 쿼리 할 수 ​​있습니다.

FetchUsers {
    users() {
        ...UserDetails
    }
}

조각과 함께 추가 필드를 추가 할 수도 있습니다 .

FetchUserById($id: ID!) {
    users(id: $id) {
        ...UserDetails
        count
    }
}

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.