企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
[TOC] #### 定义 ScalarType GraphQL规范描述了一些内置的标量类型,在graphql-php中它们作为 GraphQL\Type\Definition\Type 类的静态方法公开。 ~~~ use GraphQL\Type\Definition\Type; // Built-in Scalar types: Type::string(); // String type Type::int(); // Int type Type::float(); // Float type Type::boolean(); // Boolean type Type::id(); // ID type ~~~ 这些方法返回 GraphQL\Type\Definition\ScalarType的实例(实际上是子类之一)。你可以直接使用他们或放到自己的TypeRegistry 中 #### 自定义标量类型 除了内置标量类型,您还可以通过附加验证来定义自己的标量类型,常见的这样的类型如:Email,Date,Url 等。 为了实现你自己的类型你必须了解scalars在graphql中是如何表示的。graphql在以下情况下会对scalars进行处理。 1. 当将您的应用程序返回的值的内部表示(如,存储在数据库 或 硬编码在源代码中)转换为包含在响应(response)中的 序列化表示(serialize)。 2. 当将变量($variables )中由客户端随同GraphQL query 一起传递的输入值转换为应用程序的内部表示时。 3. 当将在 Graphql query 硬编码的输入字面量值(如 字段 参数值)转换为应用程序的内部表示时。 以上情况分别通过实现抽象类 ScalarType 的方法 serialize,pareValue and parseLiteral 来完成。 #### 注意 * 对于 pareValue 和 parseLiteral两种 除了 null 可以返回任意内置标量类型的值,如果返回的是null,表示当前值不能满足 ScalarType的 验证,则结果会抛出错误。 * parseLiteral的参数是节点对象,可能通过$valueNode->value 或取它的值 (假设变量名是$valueNode) 下面是一个简单的 Email 类型: ~~~ namespace MyApp; use GraphQL\Error\Error; use GraphQL\Language\AST\StringValueNode; use GraphQL\Type\Definition\ScalarType; use GraphQL\Utils; class EmailType extends ScalarType { // Note: name can be omitted. In this case it will be inferred from class name // (suffix "Type" will be dropped) public $name = 'Email'; /** * Serializes an internal value to include in a response. * * @param string $value * @return string */ public function serialize($value) { // Assuming internal representation of email is always correct: return $value; // If it might be incorrect and you want to make sure that only correct values are included in response - // use following line instead: // return $this->parseValue($value); } /** * Parses an externally provided value (query variable) to use as an input * * @param mixed $value * @return mixed */ public function parseValue($value) { if (!filter_var($value, FILTER_VALIDATE_EMAIL)) { throw new \UnexpectedValueException("Cannot represent value as email: " . Utils::printSafe($value)); } return $value; } /** * Parses an externally provided literal value (hardcoded in GraphQL query) to use as an input. * * E.g. * { * user(email: "user@example.com") * } * * @param \GraphQL\Language\AST\Node $valueNode * @return string * @throws Error */ public function parseLiteral($valueNode) { // Note: throwing GraphQL\Error\Error vs \UnexpectedValueException to benefit from GraphQL // error location in query: 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; } } ~~~ 或使用行间样式定义 ~~~ 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 */}, ]); ~~~