Scalar Types
内置标量类型
GraphQL 规范描述了几种内置的标量类型。在 graphql-php 中,它们作为 GraphQL\Type\Definition\Type
类的静态方法公开:
<?php
use GraphQL\Type\Definition\Type;
// 内置标量类型
Type::string(); // String 类型
Type::int(); // Int 类型
Type::float(); // Float 类型
Type::boolean(); // Boolean 类型
Type::id(); // ID 类型
这些方法返回 GraphQL\Type\Definition\ScalarType
(实际上是其中一个子类)的实例。直接在类型定义中使用它们,或者包装在 TypeRegistry 中(如果使用的话)。
编写自定义标量类型
除了内置标量类型以外,你还可以使用其他的验证规则来定义你的标量类型。
这些类型中典型的例子如 邮箱 、 日期 、 链接 等等。
想要实现你自定义的类型,你必须了解 GraphQL 中标量是如何呈现的。
在 GraphQL 中以下情况会涉及到标量:
-
当转换应用程序返回的 内部表示 (例如存储在数据库或源码中的硬编码)为包含 序列化 表示的响应时。
-
当将客户端传入的 输入值 与 GraphQL 查询一起转换为应用程序的 内部表示 时。
-
将在 GraphQL 查询(例如字段参数值)中硬编码的 文字输入值 转化为应用程序的 内部表示 时。
这些情况由抽象类 ScalarType
中的 serialize
、parseValue
和 parseLiteral
方法来分别处理。
以下是一个 邮箱 类型的简单示例:
<?php
namespace MyApp;
use GraphQL\Error\Error;
use GraphQL\Error\InvariantViolation;
use GraphQL\Language\AST\StringValueNode;
use GraphQL\Type\Definition\ScalarType;
use GraphQL\Utils\Utils;
class EmailType extends ScalarType
{
// 注意:名称可以省略。在这种情况下它将从类名推断出来
// (「Type」前缀会被去掉)
public $name = 'Email';
/**
* 在响应中包含一个序列化的内部值
*
* @param string $value
* @return string
*/
public function serialize($value)
{
// 假设邮箱的内部表示总是正确的:
return $value;
// 如果它可能不正确,并且你想确保响应中只包含正确的值。
// 请使用下面的代码:
// if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
// throw new InvariantViolation("Could not serialize following value as email: " . Utils::printSafe($value));
// }
// return $this->parseValue($value);
}
/**
* 解析外部输入的值(查询变量)以用作输入
*
* @param mixed $value
* @return mixed
*/
public function parseValue($value)
{
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
throw new Error("Cannot represent following value as email: " . Utils::printSafeJson($value));
}
return $value;
}
/**
* 解析外部输入的文字变量值(查询变量)以用作输入
*
* 例如:
* {
* user(email: "user@example.com")
* }
*
* @param \GraphQL\Language\AST\Node $valueNode
* @return string
* @throws Error
*/
public function parseLiteral($valueNode)
{
// 注意:抛出 GraphQL\Error\Error 比 \UnexpectedValueException 更有益于定位在
// GraphQL 查询的错误位置:
if (!$valueNode instanceof StringValueNode) {
throw new Error('Query error: Can only parse strings got: ' . $valueNode->kind, [$valueNode]);
}
if (!filter_var($valueNode->value, FILTER_VALIDATE_EMAIL)) {
throw new Error("Not a valid email", [$valueNode]);
}
return $valueNode->value;
}
}
或者使用行内样式:
<?php
use GraphQL\Type\Definition\CustomScalarType;
$emailType = new CustomScalarType([
'name' => 'Email',
'serialize' => function($value) {/* See function body above */},
'parseValue' => function($value) {/* See function body above */},
'parseLiteral' => function($valueNode) {/* See function body above */},
]);
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。