11# Built-in Scalar Types
2- GraphQL specification describes several built-in scalar types. In ** graphql-php** they are
3- exposed as static methods of [ ` GraphQL\Type\Definition\Type ` ] ( ../class-reference.md#graphqltypedefinitiontype ) class:
2+
3+ The GraphQL specification describes several built-in scalar types. In ** graphql-php** they are
4+ exposed as static methods of the class [ ` GraphQL\Type\Definition\Type ` ] ( ../class-reference.md#graphqltypedefinitiontype ) :
45
56``` php
6- <?php
77use GraphQL\Type\Definition\Type;
88
99// Built-in Scalar types:
@@ -13,34 +13,33 @@ Type::float(); // Float type
1313Type::boolean(); // Boolean type
1414Type::id(); // ID type
1515```
16- Those methods return instances of ` GraphQL\Type\Definition\ScalarType ` (actually one of subclasses).
16+
17+ Those methods return instances of a subclass of ` GraphQL\Type\Definition\ScalarType ` .
1718Use them directly in type definitions or wrapped in a type registry (see [ lazy loading of types] ( ../schema-definition.md#lazy-loading-of-types ) ).
1819
1920# Writing Custom Scalar Types
21+
2022In addition to built-in scalars, you can define your own scalar types with additional validation.
2123Typical examples of such types are ** Email** , ** Date** , ** Url** , etc.
2224
23- In order to implement your own type, you must understand how scalars are presented in GraphQL.
24- GraphQL deals with scalars in following cases:
25+ In order to implement your own type, you must understand how scalars are handled in GraphQL.
26+ GraphQL deals with scalars in the following cases:
2527
26- 1 . When converting ** internal representation** of value returned by your app (e.g. stored in a database
27- or hardcoded in the source code) to ** serialized** representation included in the response.
28+ 1 . Convert the ** internal representation** of a value, returned by your app (e.g. stored in a database
29+ or hardcoded in the source code), to a ** serialized representation** included in the response.
2830
29- 2 . When converting ** input value** passed by a client in variables along with GraphQL query to
30- ** internal representation** of your app .
31+ 2 . Convert an ** input value** , passed by a client in variables along with a GraphQL query, to
32+ its ** internal representation** used in your application .
3133
32- 3 . When converting ** input literal value** hardcoded in GraphQL query (e.g. field argument value) to
33- the ** internal representation** of your app .
34+ 3 . Convert an ** input literal value** , hardcoded in a GraphQL query (e.g. field argument value), to
35+ its ** internal representation** used in your application .
3436
35- Those cases are covered by methods ` serialize ` , ` parseValue ` and ` parseLiteral ` of abstract ` ScalarType `
36- class respectively.
37+ Those cases are covered by the methods ` serialize ` , ` parseValue ` and ` parseLiteral ` of the
38+ abstract class ` ScalarType ` respectively.
3739
3840Here is an example of a simple ** Email** type:
3941
4042``` php
41- <?php
42- namespace MyApp;
43-
4443use GraphQL\Error\Error;
4544use GraphQL\Error\InvariantViolation;
4645use GraphQL\Language\AST\StringValueNode;
@@ -53,62 +52,35 @@ class EmailType extends ScalarType
5352 // (suffix "Type" will be dropped)
5453 public $name = 'Email';
5554
56- /**
57- * Serializes an internal value to include in a response.
58- *
59- * @param string $value
60- * @return string
61- */
6255 public function serialize($value)
6356 {
64- // Assuming internal representation of email is always correct:
65- return $value;
66-
67- // If it might be incorrect and you want to make sure that only correct values are included
68- // in response - use following line instead:
69- // if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
70- // throw new InvariantViolation("Could not serialize following value as email: " . Utils::printSafe($value));
71- // }
72- // return $this->parseValue($value);
57+ if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
58+ throw new InvariantViolation("Could not serialize following value as email: " . Utils::printSafe($value));
59+ }
60+
61+ return $this->parseValue($value);
7362 }
7463
75- /**
76- * Parses an externally provided value (query variable) to use as an input
77- *
78- * @param mixed $value
79- * @return mixed
80- */
8164 public function parseValue($value)
8265 {
8366 if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
8467 throw new Error("Cannot represent following value as email: " . Utils::printSafeJson($value));
8568 }
69+
8670 return $value;
8771 }
8872
89- /**
90- * Parses an externally provided literal value (hardcoded in GraphQL query) to use as an input.
91- *
92- * E.g.
93- * {
94- * user(email: "
[email protected] ")
95- * }
96- *
97- * @param \GraphQL\Language\AST\Node $valueNode
98- * @param array|null $variables
99- * @return string
100- * @throws Error
101- */
10273 public function parseLiteral(Node $valueNode, ?array $variables = null)
10374 {
104- // Note: throwing GraphQL\Error\Error vs \UnexpectedValueException to benefit from GraphQL
105- // error location in query:
75+ // Throw GraphQL\Error\Error vs \UnexpectedValueException to locate the error in the query
10676 if (!$valueNode instanceof StringValueNode) {
10777 throw new Error('Query error: Can only parse strings got: ' . $valueNode->kind, [$valueNode]);
10878 }
79+
10980 if (!filter_var($valueNode->value, FILTER_VALIDATE_EMAIL)) {
11081 throw new Error("Not a valid email", [$valueNode]);
11182 }
83+
11284 return $valueNode->value;
11385 }
11486}
@@ -117,13 +89,15 @@ class EmailType extends ScalarType
11789Or with inline style:
11890
11991``` php
120- <?php
12192use GraphQL\Type\Definition\CustomScalarType;
12293
12394$emailType = new CustomScalarType([
12495 'name' => 'Email',
125- 'serialize' => function($value) {/* See function body above */},
126- 'parseValue' => function($value) {/* See function body above */},
127- 'parseLiteral' => function($valueNode, array $variables = null) {/* See function body above */},
96+ 'serialize' => static function($value) {/* See function body above */},
97+ 'parseValue' => static function($value) {/* See function body above */},
98+ 'parseLiteral' => static function(Node $valueNode, ? array $variables = null) {/* See function body above */},
12899]);
129100```
101+
102+ Keep in mind the passed functions will be called statically, so a passed in ` callable `
103+ such as ` [Foo::class, 'bar'] ` should only reference static class methods.
0 commit comments