sostariffe/php-graphql-client

GraphQL客户端和查询构建器。

1.5.1 2022-08-03 13:35 UTC

README

Build Status Codacy Badge Codacy Badge Total Downloads Latest Stable Version License

这是一个用PHP编写的GraphQL客户端,它提供非常简单但强大的查询生成类,使得与GraphQL服务器交互变得非常简单。

用法

使用此包生成GraphQL查询主要有三种方法

  1. 查询类:一个简单的类,映射到GraphQL查询。它旨在轻松快速地操作查询。
  2. QueryBuilder类:一个可以动态生成Query对象的构建器类。它设计用于在动态构建查询的情况下使用。
  3. PHP GraphQL-OQM:此包的扩展。它消除了编写任何GraphQL查询或参考API文档或语法的需要。它从API模式生成查询对象,通过GraphQL的 introspection公开的声明,然后可以简单地与之交互。

安装

运行以下命令使用composer安装包

composer require gmostafa/php-graphql-client

对象到查询映射扩展

为了避免编写任何查询并仅与从API模式生成的PHP对象交互的麻烦,请访问PHP GraphQL OQM存储库: https://github.com/mghoneimy/php-graphql-oqm

查询示例

简单查询

$gql = (new Query('companies'))
    ->setSelectionSet(
        [
            'name',
            'serialNumber'
        ]
    );

这个简单的查询将检索显示所有公司名称和序列号的查询。

嵌套查询

$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'
        ]
    );

这是参数查询的另一个特殊案例。在此示例中,我们设置一个自定义输入对象“filter”并设置一些值以限制返回的公司。我们将“filter”“name_starts_with”设置为值“Face”。此查询将仅检索名称以“Face”开头的公司。

正在构造的RawObject类用于将字符串注入到查询中,而无需进行通常由查询类执行的任何自定义格式化。

QueryBuilder类

QueryBuilder类可用于动态构建Query对象,这在某些情况下可能很有用。它的工作方式与Query类非常相似,但查询构建被分成几个步骤。

以下是如何使用QueryBuilder创建“带输入对象参数的查询”示例

$builder = (new QueryBuilder('companies'))
    ->setArgument('filter', new RawObject('{name_starts_with: "Face"}'))
    ->selectField('name')
    ->selectField('serialNumber');
$gql = $builder->getQuery();

构建客户端

通过提供GraphQL端点URL,可以轻松实例化Client对象。Client构造函数还接收一个可选的“authorizationHeaders”数组,可用于向发送到GraphQL服务器的所有请求添加授权头。

示例

$client = new Client(
    'http://api.graphql.com',
    ['Authorization' => 'Basic xyz']
);

运行查询

使用GraphQL客户端运行查询并以对象结构获取结果

$results = $client->runQuery($gql);
$results->getData()->Company[0]->branches;

或者以数组结构获取结果

$results = $client->runQuery($gql, true);
$results->getData()['Company'][1]['branches']['address']

突变(Mutations)

突变遵循GraphQL查询的相同规则,它们选择返回对象上的字段,接收参数,并可以有子字段。

以下是一个如何构建和运行突变的示例

$mutation = (new Mutation('createCompany'))
    ->setArguments(['companyObject' => new RawObject('{name: "Trial Company", employees: 200}')])
    ->setSelectionSet(
        [
            '_id',
            'name',
            'serialNumber',
        ]
    );
$results = $client->runQuery($mutation);

突变可以像查询一样由客户端运行。

实时API示例

GraphQL Pokemon是一个非常酷的公共GraphQL API,可以用来检索宝可梦数据。该API公开在网络上,我们将使用它来演示此客户端的功能。

GitHub仓库链接:https://github.com/lucasbento/graphql-pokemon

API链接:https://graphql-pokemon.now.sh/

此查询检索皮卡丘的进化形态及其攻击

{
  pokemon(name: "Pikachu") {
    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'))
    ->setArguments(['name' => 'Pikachu'])
    ->setSelectionSet(
        [
            'id',
            'number',
            'name',
            (new Query('evolutions'))
                ->setSelectionSet(
                    [
                        'id',
                        'number',
                        'name',
                        (new Query('attacks'))
                            ->setSelectionSet(
                                [
                                    (new Query('fast'))
                                        ->setSelectionSet(
                                            [
                                                'name',
                                                'type',
                                                'damage',
                                            ]
                                        )
                                ]
                            )
                    ]
                )
        ]
    );
try {
    $results = $client->runQuery($gql, true);
}
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'))
    ->setArgument('name', 'Pikachu')
    ->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 {
    $results = $client->runQuery($builder, true);
}
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->runQuery($gql);