执行查询
使用 Facade 方法
查询执行是一个复杂的过程,涉及多个步骤,包括查询 解析,
验证 和最终对你的 Schema 执行。
graphql-php 为这个过程在类中提供了一个方便的 FacadeGraphQL\GraphQL
:
<?php
use GraphQL\GraphQL;
$result = GraphQL::executeQuery(
$schema,
$queryString,
$rootValue = null,
$context = null,
$variableValues = null,
$operationName = null,
$fieldResolver = null,
$validationRules = null
);
它返回一个 GraphQL\Executor\ExecutionResult
可以轻松转换为数组的实例:
$serializableResult = $result->toArray();
返回的数组包含 数据 和 错误 键,如 GraphQL 规范所述。这个数组适合进一步的序列化(例如使用 json_encode)。另请参阅 错误处理和格式化部分。
executeQuery 方法的参数说明
参数 | 类型 | 说明 |
---|---|---|
schema | GraphQL\Type\Schema |
必须。 Schema 应用实例 |
queryString | string or GraphQL\Language\AST\DocumentNode |
必须。 解析,验证并执行现有的 GraphQL 查询字符。 如果在执行之前解析其他查询,则在此处传递相应的 AST 文档节点来避免新的解析。 |
rootValue | mixed |
表示数据图结构的基础值。作为 Query type 字段解析传递的第一个参数。如果现有该值已被 Query type 解析过,则可忽略或设置为 null 值。 |
context | mixed |
字段解析器的共享信息。 常用来传递已登录用户信息,位置详情等。 它将用在所有字段解析器的第 3 个参数。 (参考 字段定义 章节) graphql-php 不会像底层解析器那样去修改该值并传递。 |
variableValues | array |
变量的映射,该值将随同查询字符串一起传递。请查阅 GraphQL官网查询变量的相关。 |
operationName | string |
指定请求方可执行的操作, 防止条件查询字符包含多级操作。 |
fieldResolver | callable |
Schema 参数 schema 中未实现的解析器函数。如未提供,将使用 默认字段解析器。 |
validationRules | array |
查询验证规则组,默认所有规则。空数组将跳过查询验证 (对于持久化查询将会比较方便,查询会在持久化之前默认已验证,并在执行期间假设符合规则)。 |
服务器使用
如果你正在构建 HTTP GraphQL 应用,你可能需要一个稳定的服务器
(兼容 express-graphql)。
它需要支持更多的功能,比如解析 HTTP 请求,生成符合规定的响应; 批量查询;持续查询。
用法示例(PHP应用):
<?php
use GraphQL\Server\StandardServer;
$server = new StandardServer([/* server options, see below */]);
$server->handleRequest(); // parses PHP globals and emits response
服务器也要支持 PSR-7 请求/响应接口:
<?php
use GraphQL\Server\StandardServer;
use GraphQL\Executor\ExecutionResult;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface;
/** @var ServerRequestInterface $psrRequest */
/** @var ResponseInterface $psrResponse */
/** @var StreamInterface $psrBodyStream */
$server = new StandardServer([/* server options, see below */]);
$psrResponse = $server->processPsrRequest($psrRequest, $psrResponse, $psrBodyStream);
// Alternatively create PSR-7 response yourself:
/** @var ExecutionResult|ExecutionResult[] $result */
$result = $server->executePsrRequest($psrRequest);
$psrResponse = new SomePsr7ResponseImplementation(json_encode($result));
在你将服务器集成到现有的框架中时,PSR-7 变得很有用:
服务配置说明
参数 | 类型 | 说明 |
---|---|---|
schema | Schema |
必须。 Schema 应用实例 |
rootValue | mixed |
表示数据图结构的基础值。它将作为字段解析器 Query type 传递的第一个参数。 如果现有该值已被 Query type 解析过,则可忽略或设置为 null 值。 |
context | mixed |
字段解析器的共享信息。 常用来传递已登录用户信息,位置详情等。 它将用在所有字段解析器的第 3 个参数。(参考 字段定义 章节) graphql-php 不会像底层解析器那样去修改该值并传递。 |
fieldResolver | callable |
参数 schema 中未实现的解析器函数。如未提供, 将使用 默认字段解析器。 |
validationRules | array or callable |
查询验证规则组,默认所有规则。空数组将跳过查询验证 (对于持久化查询将会比较方便,查询会在持久化之前默认已验证,并在执行期间假设符合规则)。 传入 callable 将会对不同的查询返回不同的验证规则 (例如:空数组持久化查询和全列表的规则常规查询)。 如果传入,它将应该使用以下形式: function (OperationParams $params, DocumentNode $node, $operationType): array |
queryBatching | bool |
服务是否支持批处理查询的标志 (apollo-style). 默认为 false |
debug | int |
调试标志。查阅 错误调试 (标志值相同)。 |
persistentQueryLoader | callable |
在 query 过程中,当服务请求包含 queryId 参数,使用此函数调用来获取真正的查询。 服务不会实现持久化部分(必须自己实现),但是它允许执行先前被持久化的查询。 函数形式如下: function ($queryId, OperationParams $params) 函数应返回 string 或被解析过的 DocumentNode 更多关于持久化查询。 |
errorFormatter | callable |
自定义错误格式。查阅 错误处理。 |
errorsHandler | callable |
自定义错误处理。查阅 错误处理。 |
promiseAdapter | PromiseAdapter |
只在 异步PHP 中使用。 |
服务配置实例
如果想在交互界面实现 自动完成 和 静态验证,
使用 GraphQL\Server\ServerConfig
替代数组:
<?php
use GraphQL\Server\ServerConfig;
use GraphQL\Server\StandardServer;
$config = ServerConfig::create()
->setSchema($schema)
->setErrorFormatter($myFormatter)
->setDebug($debug)
;
$server = new StandardServer($config);
查询批处理
标准服务器支持查询批处理 (apollo 样式)。
Server 对一系列 executeQuery() 调用的主要优点之一是,
Deferred 解释器 不会被隔离在查询中。例如,下面的批处理将需要单个数据库请求(如果用户字段被延迟):
[
{
"query": "{user(id: 1)} { id }"
},
{
"query": "{user(id: 2)} { id }"
},
{
"query": "{user(id: 3)} { id }"
}
]
要启用查询批处理,请在服务器配置中传递 queryBatching 选项:
<?php
use GraphQL\Server\StandardServer;
$server = new StandardServer([
'queryBatching' => true
]);
自定义验证规则
在执行查询之前,「GraphQL」将使用特有的标准规则来进行查询验证。
你可以选择在「全局上」或者「执行时」覆盖原有标准规则。
添加全局规则:
<?php
use GraphQL\Validator\Rules;
use GraphQL\Validator\DocumentValidator;
// 全局设置
DocumentValidator::addRule(new Rules\DisableIntrospection());
自定义规则并添加验证:
<?php
use GraphQL\GraphQL;
use GraphQL\Validator\Rules;
$myValiationRules = array_merge(
GraphQL::getStandardValidationRules(),
[
new Rules\QueryComplexity(100),
new Rules\DisableIntrospection()
]
);
$result = GraphQL::executeQuery(
$schema,
$queryString,
$rootValue = null,
$context = null,
$variableValues = null,
$operationName = null,
$fieldResolver = null,
$myValiationRules // <-- 本次请求中,自定义规则将覆盖全局规则
);
或者使用标准化服务添加验证:
<?php
use GraphQL\Server\StandardServer;
$server = new StandardServer([
'validationRules' => $myValiationRules
]);
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。