cfpinto / graphql
一个 GraphQL 查询构建类
v2.0.0
2023-01-20 17:13 UTC
Requires
- php: 8.*
- ext-json: *
Requires (Dev)
- phpmd/phpmd: ^2.13
- phpunit/phpunit: ^9.5
- spatie/phpunit-watcher: ^1.23
- squizlabs/php_codesniffer: ^3.7
- symfony/var-dumper: ^6.2
README
变更日志
在这个版本中,对代码组织和实体管理进行了大量重写。在这个重写级别上保持向后兼容性比较困难,但我尽力做到了。
下个版本将删除一些弃用通知
- 将删除根级类,以支持上下文命名空间(GraphQL\Mutation => GraphQL\Actions\Mutation)
- 解析器和实体将被解耦,您将被强制在实体构造函数中注入解析器
- 使用
on()
方法作为语法糖,可能会被弃用,以使用 InlineFragment 实例在 use 方法中传递
它的工作原理
编写 GraphQL 查询可能是一个痛苦的过程。使用 GraphpQL 查询构建器编写 PHP 并获取 GraphQL
示例
当寻找一个英雄作为他的副手时,一个人会发现自己被那里众多的英雄数量所淹没。这里有各种各样的英雄,让我们列出他们所有人
字段
$hero = new \GraphQL\Actions\Query('hero'); echo $hero->use('name') ->friends ->use('name') ->root() ->query();
将生成
{
hero {
name
friends {
name
}
}
}
参数
一个英雄将有很多朋友,这可能使他难以行走,限制英雄的朋友为 2 将很棒
$hero = new \GraphQL\Actions\Query('hero'); echo $hero->use('name') ->friends(['first'=>2]) ->use('name') ->root() ->query();
将生成
{
hero {
name
friends(first: 2) {
name
}
}
}
返回树
有时你可能需要了解更多关于这位英雄的信息,比如当你想知道英雄的朋友和服装时。为此,我们需要回到英雄树。为此,我们将使用 $node->prev()
$hero = new \GraphQL\Actions\Query('hero'); echo $hero->use('name') ->friends(['first'=>2]) ->use('name') ->prev() ->costumes ->color ->root() ->query();
将生成
{
hero {
name
friends(first: 2) {
name
}
costumes {
color
}
}
}
内联片段
有时你并不完全清楚你寻找的英雄的类型。也许你寻找一个会飞的英雄,也许是一个强大的英雄
$hero = new \GraphQL\Actions\Query('hero'); echo $hero->use('name') ->on('FlyingHero') ->use('hasCape') ->prev() ->on('StrongHero') ->use('strengthLevel') ->prev() ->friends(['first'=>2]) ->use('name') ->prev() ->costumes ->color ->root() ->query();
将生成
{
hero {
name
... on FlyingHero {
hasCape
}
... on StrongHero {
strengthLevel
}
friends(first: 2) {
name
}
costumes {
color
}
}
}
别名
为了惊喜,你可能需要将一些英雄的属性命名为不同的名称;你可能想将朋友称为 partners_in_good 或将名字称为 call_me_this
$hero = new \GraphQL\Actions\Query('hero'); echo $hero->use('name') ->alias('call_me_this', 'name') ->friends(['first'=>2]) ->alias('partners_in_good') ->use('name') ->prev() ->costumes ->color ->root() ->query();
将生成
{
hero {
call_me_this: name
partners_in_good: friends(first: 2) {
name
}
costumes {
color
}
}
}
片段
抱歉没有从这里开始的超级英雄叙述:D。坚持使用老式的技术解释
要使用片段,就像声明一个图一样声明片段,然后在 ->use()
调用中像使用常规属性一样使用它
$fragment = new GraphQL\Entities\Fragment('properties', 'Hero'); $fragment->use('id', 'age'); $hero = new \GraphQL\Actions\Query('hero'); echo $hero->use('name', $fragment)->query(); echo $fragment->query();
将生成
{
hero {
name
...properties
}
}
fragment properties on Hero {
id
age
}
变量
使用变量的感觉不那么必要,因为我们使用 PHP 来构建查询。然而...
$variable = new GraphQL\Entities\Variable('name', 'String'); $hero = new \GraphQL\Actions\Query('hero', ['name' => $variable]); echo $hero->use('name')->query();
将生成
query getGraph($name: String){
hero(name: $name) {
name
}
}
元字段
您也可以像请求属性一样使用元字段
$variable = new GraphQL\Entities\Variable('name', 'String'); $hero = new \GraphQL\Actions\Query('hero', ['name' => $variable]); echo $hero->use('name', '__typename')->query();
将生成
query getGraph($name: String){
hero(name: $name) {
name
__typename
}
}
这也可能被别称
$variable = new GraphQL\Entities\Variable('name', 'String'); $hero = new \GraphQL\Actions\Query('hero', ['name' => $variable]); echo $hero->use('name', '__typename') ->alias('type', '__typename') ->query();
将生成
query getGraph($name: String){
hero(name: $name) {
name
type: __typename
}
}
突变
在你选择了你的英雄,并且他让你成为他的副手之后,他甚至会让你帮助他做一些日常的例行公事。他甚至可能让你选择他的服装颜色。这有多么酷?
$mutation = new GraphQL\Actions\Mutation('changeHeroCostumeColor', ['id' => 'theHeroId', 'color'=>'red']); $mutation ->hero ->use('name') ->costumes ->use('color') ->root() ->query();
将生成
mutation changeHeroCostumeColor(id: 'theHeroId', color: 'red') {
hero {
name
costumes {
color
}
}
}
带有变量
$mutation = new GraphQL\Actions\Mutation('changeHeroCostumeColor', ['id' => new GraphQL\Entities\Variable('uuid', 'String', ''), new GraphQL\Entities\Variable('color', 'String', '')]); $mutation ->hero ->use('name') ->costumes ->use('color') ->root() ->query();
将生成
mutation ChangeHeroCostumeColorMutation($uuid: String, $color: String) {
changeHeroCostumeColorAction(id: $uuid, color: $color) {
hero {
name
costumes {
color
}
}
}
}