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ライブラリを使用しています。
残念ながら、やりたいことはできません。 GraphQLでは、クエリから返されるフィールドを明示的に指定する必要があります。
はい、あなたはcanintrospection を使用してこれを行うことができます。 (タイプUserTypeのような)GraphQLクエリを作成します
{
__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. ...)
]
}
}
}
次に、クライアントでこのフィールドのリストを読み取り、2番目のGraphQLクエリを動的に構築して、これらのすべてのフィールドを取得できます。
これは、フィールドを取得するタイプの名前を知っていることを前提としています。タイプがわからない場合は、次のようなイントロスペクションを使用して、すべてのタイプとフィールドを一緒に取得できます。
{
__schema {
types {
name
fields {
name
description
}
}
}
}
注:これは有線のGraphQLデータです。実際のクライアントで読み書きする方法を自分で考えてください。 graphQL javascriptライブラリは、ある程度のイントロスペクションを既に使用している場合があります。たとえば、 apollo codegen コマンドは、イントロスペクションを使用して型を生成します。
これを行う唯一の方法は、再利用可能なフラグメントを利用することです。
fragment UserFragment on Users {
id
username
count
}
FetchUsers {
users(id: "2") {
...UserFragment
}
}
Google Places APIからデータベースにシリアル化した位置データを読み込む必要があるときに、この同じ問題に直面しました。一般に、マップ全体で機能するようにしたいのですが、毎回すべてのフィールドを指定する必要はありませんでした。
私はRubyで働いていたので、PHP実装を提供することはできませんが、原則は同じでなければなりません。
リテラルJSONオブジェクトを返すだけのJSONというカスタムスカラー型を定義しました。
Ruby実装はそのようでした(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のオブジェクトを無効にします。