PHP で書かれた GraphQL クライアント。非常にシンプルでありながら強力なクエリ ジェネレーター クラスを提供し、GraphQL サーバーとの対話プロセスを非常に簡単にします。
このパッケージを使用して GraphQL クエリを生成するには、主に 3 つの方法があります。
Query
オブジェクトを動的に生成するために使用できるビルダー クラス。これは、クエリが動的に構築される場合に使用されるように設計されています。次のコマンドを実行して、composer を使用してパッケージをインストールします。
$ composer require gmostafa/php-graphql-client
クエリを記述する煩わしさを回避し、API スキーマから生成された PHP オブジェクトを操作するだけするには、PHP GraphQL OQM リポジトリにアクセスしてください。
$ gql = ( new Query ( ' companies ' ))
-> setSelectionSet (
[
' name ' ,
' serialNumber '
]
);
この単純なクエリでは、名前とシリアル番号を表示するすべての企業が取得されます。
前の例で提供されたクエリは、「短縮形式」で表されています。短縮形式では、記述するコード行の数が減り、クエリを記述するプロセスが高速化されます。以下は、前の例で作成したまったく同じクエリの完全な形式の例です。
$ gql = ( new Query ())
-> setSelectionSet (
[
( new Query ( ' companies ' ))
-> setSelectionSet (
[
' name ' ,
' serialNumber '
]
)
]
);
例に見られるように、短縮形式は読み書きが簡単であるため、一般に完全形式と比較して使用することが好まれます。
同じオブジェクト内で複数のクエリを実行する場合、クエリが 1 つのケースしかない短縮形式で表現できない場合を除き、完全な形式は使用しないでください。
$ gql = ( new Query ())
-> setSelectionSet (
[
( new Query ( ' companies ' ))
-> setSelectionSet (
[
' name ' ,
' serialNumber '
]
),
( new Query ( ' countries ' ))
-> setSelectionSet (
[
' name ' ,
' code ' ,
]
)
]
);
このクエリは、すべての企業と国を取得し、それぞれのデータ フィールドを表示します。基本的に、1 つのクエリ オブジェクト エンベロープで 2 つ (必要に応じてそれ以上) の独立したクエリを実行します。
複数のクエリを記述するには、各クエリを親クエリ オブジェクトの下のサブフィールドとして表す完全な形式でクエリ オブジェクトを記述する必要があります。
$ gql = ( new Query ( ' companies ' ))
-> setSelectionSet (
[
' name ' ,
' serialNumber ' ,
( new Query ( ' branches ' ))
-> setSelectionSet (
[
' address ' ,
( new Query ( ' contracts ' ))
-> setSelectionSet ([ ' date ' ])
]
)
]
);
このクエリはより複雑で、スカラー フィールドだけでなくオブジェクト フィールドも取得します。このクエリは、すべての会社を返し、その名前、シリアル番号を表示し、各会社についてはそのすべての支店を返し、支店の住所を表示します。また、住所ごとに、この住所にバインドされているすべての契約を取得して日付を表示します。
$ gql = ( new Query ( ' companies ' ))
-> setArguments ([ ' name ' => ' Tech Co. ' , ' first ' => 3 ])
-> setSelectionSet (
[
' name ' ,
' serialNumber '
]
);
このクエリは、引数を追加してすべての企業を取得するわけではありません。このクエリは、「Tech Co.」という名前を持つ最初の 3 つの企業を取得し、その名前とシリアル番号を表示します。
$ gql = ( new Query ( ' companies ' ))
-> setArguments ([ ' serialNumbers ' => [ 159 , 260 , 371 ]])
-> setSelectionSet (
[
' name ' ,
' serialNumber '
]
);
このクエリは、引数クエリの特殊なケースです。この例では、クエリはシリアル番号が 159、260、および 371 のいずれかである会社のみを取得し、名前とシリアル番号を表示します。
$ gql = ( new Query ( ' companies ' ))
-> setArguments ([ ' filter ' => new RawObject ( ' {name_starts_with: "Face"} ' )])
-> setSelectionSet (
[
' name ' ,
' serialNumber '
]
);
このクエリは、引数クエリの別の特殊なケースです。この例では、返される企業を制限するためにいくつかの値を含むカスタム入力オブジェクト「フィルター」を設定しています。フィルター「name_starts_with」を値「Face」で設定します。このクエリは、名前が「Face」という語句で始まる企業のみを取得します。
構築中の RawObject クラスは、文字列をそのままクエリに注入するために使用されます。 RawObject コンストラクターに入力された文字列は、クエリ クラスによって通常行われるカスタム フォーマットなしで、そのままクエリに入力されます。
$ gql = ( new Query ( ' companies ' ))
-> setVariables (
[
new Variable ( ' name ' , ' String ' , true ),
new Variable ( ' limit ' , ' Int ' , false , 5 )
]
)
-> setArguments ([ ' name ' => ' $name ' , ' first ' => ' $limit ' ])
-> setSelectionSet (
[
' name ' ,
' serialNumber '
]
);
このクエリは、このパッケージで変数を使用して、GraphQL 標準によって有効になる動的リクエストを可能にする方法を示しています。
Variable クラスは、GraphQL 標準の変数を表す不変クラスです。そのコンストラクターは 4 つの引数を受け取ります。
$ gql = ( new Query ())
-> setSelectionSet (
[
( new Query ( ' companies ' , ' TechCo ' ))
-> setArguments ([ ' name ' => ' Tech Co. ' ])
-> setSelectionSet (
[
' name ' ,
' serialNumber '
]
),
( new Query ( ' companies ' , ' AnotherTechCo ' ))
-> setArguments ([ ' name ' => ' A.N. Other Tech Co. ' ])
-> setSelectionSet (
[
' name ' ,
' serialNumber '
]
)
]
);
同じオブジェクトを異なる引数で複数回取得する必要がある場合は、Query コンストラクターの 2 番目の引数にエイリアスを設定できます。
$ gql = ( new Query ( ' companies ' ))
-> setAlias ( ' CompanyAlias ' )
-> setSelectionSet (
[
' name ' ,
' serialNumber '
]
);
エイリアスは setter メソッド経由で設定することもできます。
インターフェイス型を返すフィールドをクエリする場合、基になる具象型のデータにアクセスするためにインライン フラグメントを使用することが必要になる場合があります。
この例は、このパッケージを使用してインライン フラグメントを生成する方法を示しています。
$ gql = new Query ( ' companies ' );
$ gql -> setSelectionSet (
[
' serialNumber ' ,
' name ' ,
( new InlineFragment ( ' PrivateCompany ' ))
-> setSelectionSet (
[
' boardMembers ' ,
' shareholders ' ,
]
),
]
);
QueryBuilder クラスを使用すると、Query オブジェクトを動的に構築でき、場合によっては便利です。 Query クラスと非常によく似た動作をしますが、Query の構築はいくつかのステップに分かれています。
これが、QueryBuilder を使用して「入力オブジェクト引数を使用したクエリ」の例を作成する方法です。
$ builder = ( new QueryBuilder ( ' companies ' ))
-> setVariable ( ' namePrefix ' , ' String ' , true )
-> setArgument ( ' filter ' , new RawObject ( ' {name_starts_with: $namePrefix} ' ))
-> selectField ( ' name ' )
-> selectField ( ' serialNumber ' );
$ gql = $ builder -> getQuery ();
Query クラスと同様に、コンストラクターの 2 番目の引数を使用してエイリアスを設定できます。
$ builder = ( new QueryBuilder ( ' companies ' , ' CompanyAlias ' ))
-> selectField ( ' name ' )
-> selectField ( ' serialNumber ' );
$ gql = $ builder -> getQuery ();
またはセッターメソッド経由
$ builder = ( new QueryBuilder ( ' companies ' ))
-> setAlias ( ' CompanyAlias ' )
-> selectField ( ' name ' )
-> selectField ( ' serialNumber ' );
$ gql = $ builder -> getQuery ();
Query クラスと同様に、QueryBuilder クラスも完全な形式で記述して、1 つのクエリ ビルダー オブジェクトの下に複数のクエリを記述できるようにすることができます。以下は、完全なフォームを QueryBuilder で使用する方法の例です。
$ builder = ( new QueryBuilder ())
-> setVariable ( ' namePrefix ' , ' String ' , true )
-> selectField (
( new QueryBuilder ( ' companies ' ))
-> setArgument ( ' filter ' , new RawObject ( ' {name_starts_with: $namePrefix} ' ))
-> selectField ( ' name ' )
-> selectField ( ' serialNumber ' )
)
-> selectField (
( new QueryBuilder ( ' company ' ))
-> setArgument ( ' serialNumber ' , 123 )
-> selectField ( ' name ' )
);
$ gql = $ builder -> getQuery ();
このクエリは、前の例のクエリを拡張したものです。これは、名前のプレフィックスで始まるすべての会社を返し、値 123 のserialNumber
を持つ会社を、どちらも同じ応答で返します。
Client オブジェクトは、GraphQL エンドポイント URL を指定することで簡単にインスタンス化できます。
Client コンストラクターは、オプションの「authorizationHeaders」配列も受け取ります。これを使用して、GraphQL サーバーに送信されるすべてのリクエストに認可ヘッダーを追加できます。
例:
$ client = new Client (
' http://api.graphql.com ' ,
[ ' Authorization ' => ' Basic xyz ' ]
);
Client コンストラクターは、オプションの "httpOptions" 配列も受け取ります。これは "authorizationHeaders"をオーバーライドし、カスタム Guzzle HTTP クライアント リクエスト オプションを追加するために使用できます。
例:
$ client = new Client (
' http://api.graphql.com ' ,
[],
[
' connect_timeout ' => 5 ,
' timeout ' => 5 ,
' headers ' => [
' Authorization ' => ' Basic xyz '
'User-Agent' => ' testing/1.0 ' ,
],
' proxy ' => [
' http ' => ' tcp://localhost:8125 ' , // Use this proxy with "http"
' https ' => ' tcp://localhost:9124 ' , // Use this proxy with "https",
' no ' => [ ' .mit.edu ' , ' foo.com ' ] // Don't use a proxy with these
],
' cert ' => [ ' /path/server.pem ' , ' password ' ]
. . .
]
);
PSR-18 インターフェイスを実装する独自の事前設定された HTTP クライアントを使用することができます。
例:
$ client = new Client (
' http://api.graphql.com ' ,
[],
[],
$ myHttpClient
);
GraphQL クライアントでクエリを実行し、結果をオブジェクト構造で取得します。
$ results = $ client -> runQuery ( $ gql );
$ results -> getData ()-> companies [ 0 ]-> branches ;
または、配列構造で結果を取得します。
$ results = $ client -> runQuery ( $ gql , true );
$ results -> getData ()[ ' companies ' ][ 1 ][ ' branches ' ][ ' address ' ];
変数を含むクエリを実行するには、変数名 (キー) を変数値 (値) にマップする連想配列をrunQuery
メソッドに渡す必要があります。以下に例を示します。
$ gql = ( new Query ( ' companies ' ))
-> setVariables (
[
new Variable ( ' name ' , ' String ' , true ),
new Variable ( ' limit ' , ' Int ' , false , 5 )
]
)
-> setArguments ([ ' name ' => ' $name ' , ' first ' => ' $limit ' ])
-> setSelectionSet (
[
' name ' ,
' serialNumber '
]
);
$ variablesArray = [ ' name ' => ' Tech Co. ' , ' first ' => 5 ];
$ results = $ client -> runQuery ( $ gql , true , $ variablesArray );
ミューテーションは、GraphQL のクエリと同じルールに従い、返されたオブジェクトのフィールドを選択し、引数を受け取り、サブフィールドを持つことができます。
ミューテーションを構築して実行する方法のサンプル例を次に示します。
$ mutation = ( new Mutation ( ' createCompany ' ))
-> setArguments ([ ' companyObject ' => new RawObject ( ' {name: "Trial Company", employees: 200} ' )])
-> setSelectionSet (
[
' _id ' ,
' name ' ,
' serialNumber ' ,
]
);
$ results = $ client -> runQuery ( $ mutation );
ミューテーションは、クエリを実行するのと同じ方法でクライアントによって実行できます。
ミューテーションでは、クエリと同じ方法で変数を利用できます。以下は、変数を使用して入力オブジェクトを GraphQL サーバーに動的に渡す方法の例です。
$ mutation = ( new Mutation ( ' createCompany ' ))
-> setVariables ([ new Variable ( ' company ' , ' CompanyInputObject ' , true )])
-> setArguments ([ ' companyObject ' => ' $company ' ]);
$ variables = [ ' company ' => [ ' name ' => ' Tech Company ' , ' type ' => ' Testing ' , ' size ' => ' Medium ' ]];
$ client -> runQuery (
$ mutation , true , $ variables
);
これらは、結果として生じる突然変異と、それとともに渡される変数です。
mutation( $ company : CompanyInputObject!) {
createCompany (companyObject: $ company )
}
{"company":{"name":"Tech Company", " type " :"Testing", " size " :"Medium"}}
GraphQL Pokémon は、ポケモン データを取得するために使用できる非常に優れたパブリック GraphQL API です。 API は Web 上で公開されており、このクライアントの機能をデモするために使用します。
Github リポジトリリンク: https://github.com/lucasbento/graphql-pokemon
APIリンク:https://graphql-pokemon.now.sh/
このクエリは、ポケモンの進化とその攻撃を取得します。
query( $ name : String!) {
pokemon (name: $ name ) {
id
number
name
evolutions {
id
number
name
weight {
minimum
maximum
}
attacks {
fast {
name
type
damage
}
}
}
}
}
このようにして、クエリ クラスを使用してこのクエリを作成し、クライアントを使用して実行できます。
$ client = new Client (
' https://graphql-pokemon.now.sh/ '
);
$ gql = ( new Query ( ' pokemon ' ))
-> setVariables ([ new Variable ( ' name ' , ' String ' , true )])
-> setArguments ([ ' name ' => ' $name ' ])
-> setSelectionSet (
[
' id ' ,
' number ' ,
' name ' ,
( new Query ( ' evolutions ' ))
-> setSelectionSet (
[
' id ' ,
' number ' ,
' name ' ,
( new Query ( ' attacks ' ))
-> setSelectionSet (
[
( new Query ( ' fast ' ))
-> setSelectionSet (
[
' name ' ,
' type ' ,
' damage ' ,
]
)
]
)
]
)
]
);
try {
$ name = readline ( ' Enter pokemon name: ' );
$ results = $ client -> runQuery ( $ gql , true , [ ' name ' => $ name ]);
}
catch ( QueryError $ exception ) {
print_r ( $ exception -> getErrorDetails ());
exit ;
}
print_r ( $ results -> getData ()[ ' pokemon ' ]);
あるいは、QueryBuilder クラスを使用してこのクエリを生成することもできます。
$ client = new Client (
' https://graphql-pokemon.now.sh/ '
);
$ builder = ( new QueryBuilder ( ' pokemon ' ))
-> setVariable ( ' name ' , ' String ' , true )
-> setArgument ( ' name ' , ' $name ' )
-> selectField ( ' id ' )
-> selectField ( ' number ' )
-> selectField ( ' name ' )
-> selectField (
( new QueryBuilder ( ' evolutions ' ))
-> selectField ( ' id ' )
-> selectField ( ' name ' )
-> selectField ( ' number ' )
-> selectField (
( new QueryBuilder ( ' attacks ' ))
-> selectField (
( new QueryBuilder ( ' fast ' ))
-> selectField ( ' name ' )
-> selectField ( ' type ' )
-> selectField ( ' damage ' )
)
)
);
try {
$ name = readline ( ' Enter pokemon name: ' );
$ results = $ client -> runQuery ( $ builder , true , [ ' name ' => $ name ]);
}
catch ( QueryError $ exception ) {
print_r ( $ exception -> getErrorDetails ());
exit ;
}
print_r ( $ results -> getData ()[ ' pokemon ' ]);
このパッケージの主な目的ではありませんが、 Client
クラスのrunRawQuery
メソッドを使用する他のクライアントと同様に、生の文字列クエリの実行をサポートします。使用方法の例を次に示します。
$ gql = <<<QUERY
query {
pokemon(name: "Pikachu") {
id
number
name
attacks {
special {
name
type
damage
}
}
}
}
QUERY ;
$ results = $ client -> runRawQuery ( $ gql );