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 {
pokemon(name: "Pikachu") {
id
number
name
attacks {
special {
name
type
damage
}
}
}
}
QUERY ;
$ results = $ client -> runRawQuery ( $ gql );通过命令行克隆项目: