php graphql client
用PHP编写的GraphQL客户端,提供非常简单但功能强大的查询生成器类,使与GraphQl Server交互的过程非常简单。
用法
有3种主要方法可以使用此软件包生成您的GraphQl查询:
- 查询类:映射到GraphQl查询的简单类。它旨在轻松和速度操纵查询。
- QueryBuilder类:可动态生成
Query对象的构建器类。在以动态方式构建查询的情况下,它将使用它。 - PHP GraphQL-OQM:此软件包的扩展名。它消除了编写任何GraphQl查询或参考API文档或语法的需求。它从API架构中生成查询对象,通过GraphQl的内省显示的声明,然后可以简单地与之相互作用。
安装
运行以下命令使用Composer安装软件包:
$ composer require gmostafa/php-graphql-client
对象到Query-Mapper扩展
为了避免不得不编写任何查询的麻烦,只是与您的API架构生成的PHP对象进行交互
查询示例
简单查询
$ gql = ( new Query ( \' companies \' )) -> setSelectionSet ( [ \' name \' , \' serialNumber \' ] );
这个简单的查询将检索所有显示其姓名和序列号的公司。
完整的形式
上一个示例中提供的查询以“速记形式”表示。速记形式涉及编写减少的代码线,从而加快了搅拌Querries的过程。以下是上一个示例中完全相同的查询的完整表单的一个示例。
$ gql = ( new Query ()) -> setSelectionSet ( [ ( new Query ( \' companies \' )) -> setSelectionSet ( [ \' name \' , \' serialNumber \' ] ) ] );
如示例所示,速记形式更简单地读写,与完整形式相比,它通常更喜欢使用。
除非无法以速记表单表示查询,否则不应使用完整的表单,当我们想在同一对象中运行多个查询时,只有一个情况。
多个查询
$ gql = ( new Query ()) -> setSelectionSet ( [ ( new Query ( \' companies \' )) -> setSelectionSet ( [ \' name \' , \' serialNumber \' ] ), ( new Query ( \' countries \' )) -> setSelectionSet ( [ \' name \' , \' code \' , ] ) ] );
此查询会检索所有公司和国家 /地区都显示每个数据字段。它基本上在一个查询对象信封中运行两个(或更多)独立查询。
编写多个查询需要以完整形式编写查询对象,以将每个查询表示为父级查询对象下的子字段。
嵌套查询
$ 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.”的名称检索前三家公司,并显示其名称和序列号。
与数组参数查询
$ 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 \' ] );
此查询是参数查询的另一个特殊情况。在此示例中,我们将设置一个具有一些值的自定义输入对象“过滤器”,以限制返回的公司。我们将使用值“ face”设置过滤器“ name_starts_with”。此查询将仅检索名称以“ 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标准启用动态请求。
变量类
变量类是一个不变的类,代表GraphQL标准中的变量。它的构造函数收到4个参数:
- 名称:代表变量名称
- 类型:根据GraphQL Server架构表示变量类型
- iSrequired(可选):表示是否需要该变量,默认情况下是错误的
- DefaultValue(可选):表示要分配给变量的默认值。仅当将ISREQUIRED参数设置为false时,才会考虑默认值。
使用别名
$ 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 \' ] ) ] );
在需要多次以不同参数检索相同对象的情况下,可以在查询构造函数的第二个参数中设置别名。
$ gql = ( new Query ( \' companies \' )) -> setAlias ( \' CompanyAlias \' ) -> setSelectionSet ( [ \' name \' , \' serialNumber \' ] );
别名也可以通过设置方法设置。
使用接口:与内联片段查询
查询返回接口类型的字段时,您可能需要使用内联片段来访问基础混凝土类型的数据。
此示例显示了如何使用此软件包生成内联片段:
$ gql = new Query ( \' companies \' ); $ gql -> setSelectionSet ( [ \' serialNumber \' , \' name \' , ( new InlineFragment ( \' PrivateCompany \' )) -> setSelectionSet ( [ \' boardMembers \' , \' shareholders \' , ] ), ] );
查询构建器
QueryBuilder类可用于动态构造查询对象,在某些情况下这很有用。它的工作原理与查询类非常相似,但是查询建筑物分为步骤。
这就是可以使用QueryBuilder创建“使用输入对象参数的查询”示例的方式:
$ builder = ( new QueryBuilder ( \' companies \' )) -> setVariable ( \' namePrefix \' , \' String \' , true ) -> setArgument ( \' filter \' , new RawObject ( \' {name_starts_with: $namePrefix} \' )) -> selectField ( \' name \' ) -> selectField ( \' serialNumber \' ); $ gql = $ builder -> getQuery ();
与查询类一样,可以使用第二个构造函数参数设置别名。
$ builder = ( new QueryBuilder ( \' companies \' , \' CompanyAlias \' )) -> selectField ( \' name \' ) -> selectField ( \' serialNumber \' ); $ gql = $ builder -> getQuery ();
或通过Setter方法
$ builder = ( new QueryBuilder ( \' companies \' )) -> setAlias ( \' CompanyAlias \' ) -> selectField ( \' name \' ) -> selectField ( \' serialNumber \' ); $ gql = $ builder -> getQuery ();
完整的形式
就像查询类一样,可以完整地编写QueryBuilder类,以在一个查询构建器对象下编写多个查询。以下是一个示例,说明如何将完整表单与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名单。
构建客户
通过提供GraphQl端点URL可以轻松实例化客户端对象。
客户端构造函数还接收一个可选的“授权台面”数组,可用于将授权标头添加到发送到GraphQL Server的所有请求中。
例子:
$ client = new Client ( \' http://api.g*r*ap*hql.com \' , [ \' Authorization \' => \' Basic xyz \' ] );
客户端构造函数还接收一个可选的“ HTTPoptions”数组,该数组覆盖了“授权头”,可用于添加自定义Guzles HTTP http client Request request选项。
例子:
$ client = new Client ( \' http://api.g*r*ap*hql.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 \' ] . . . ] );
可以使用您自己的预先配置的HTTP客户端来实现PSR-18接口。
例子:
$ client = new Client ( \' http://api.g*r*ap*hql.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 Server的一个示例:
$ 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\"}}
实时API示例
GraphQl Pokemon是一种非常酷的公共GraphQl API,可用于检索口袋妖怪数据。 API在网络上公开可用,我们将使用它来演示该客户端的功能。
github repo链接: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.*n*o*w.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.*n*o*w.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 );
