Better custom scalars in blog example + more comments

This commit is contained in:
vladar 2016-11-02 05:10:04 +07:00
parent 1672bd33e3
commit eb3f54b98e
2 changed files with 43 additions and 29 deletions

View File

@ -1,6 +1,7 @@
<?php <?php
namespace GraphQL\Examples\Blog\Type\Scalar; namespace GraphQL\Examples\Blog\Type\Scalar;
use GraphQL\Error\Error;
use GraphQL\Examples\Blog\Type\BaseType; use GraphQL\Examples\Blog\Type\BaseType;
use GraphQL\Language\AST\StringValue; use GraphQL\Language\AST\StringValue;
use GraphQL\Type\Definition\CustomScalarType; use GraphQL\Type\Definition\CustomScalarType;
@ -22,26 +23,26 @@ class EmailType extends BaseType
/** /**
* Serializes an internal value to include in a response. * Serializes an internal value to include in a response.
* *
* @param mixed $value * @param string $value
* @return mixed * @return string
*/ */
public function serialize($value) public function serialize($value)
{ {
return $this->coerceEmail($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 to use as an input * Parses an externally provided value (query variable) to use as an input
* *
* @param mixed $value * @param mixed $value
* @return mixed * @return mixed
*/ */
public function parseValue($value) public function parseValue($value)
{
return $this->coerceEmail($value);
}
private function coerceEmail($value)
{ {
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) { if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
throw new \UnexpectedValueException("Cannot represent value as email: " . Utils::printSafe($value)); throw new \UnexpectedValueException("Cannot represent value as email: " . Utils::printSafe($value));
@ -50,16 +51,22 @@ class EmailType extends BaseType
} }
/** /**
* Parses an externally provided literal value to use as an input * Parses an externally provided literal value (hardcoded in GraphQL query) to use as an input
* *
* @param \GraphQL\Language\AST\Value $valueAST * @param \GraphQL\Language\AST\Node $valueAST
* @return mixed * @return string
* @throws Error
*/ */
public function parseLiteral($valueAST) public function parseLiteral($valueAST)
{ {
if ($valueAST instanceof StringValue) { // Note: throwing GraphQL\Error\Error vs \UnexpectedValueException to benefit from GraphQL
// error location in query:
if (!$valueAST instanceof StringValue) {
throw new Error('Query error: Can only parse strings got: ' . $valueAST->kind, [$valueAST]);
}
if (!filter_var($valueAST->value, FILTER_VALIDATE_EMAIL)) {
throw new Error("Not a valid email", [$valueAST]);
}
return $valueAST->value; return $valueAST->value;
} }
return null;
}
} }

View File

@ -1,6 +1,8 @@
<?php <?php
namespace GraphQL\Examples\Blog\Type\Scalar; namespace GraphQL\Examples\Blog\Type\Scalar;
use GraphQL\Error\Error;
use GraphQL\Language\AST\Node;
use GraphQL\Language\AST\StringValue; use GraphQL\Language\AST\StringValue;
use GraphQL\Type\Definition\ScalarType; use GraphQL\Type\Definition\ScalarType;
use GraphQL\Utils; use GraphQL\Utils;
@ -17,25 +19,21 @@ class UrlType extends ScalarType
*/ */
public function serialize($value) public function serialize($value)
{ {
return $this->coerceUrl($value); // Assuming internal representation of url 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 to use as an input * Parses an externally provided value (query variable) to use as an input
* *
* @param mixed $value * @param mixed $value
* @return mixed * @return mixed
*/ */
public function parseValue($value) public function parseValue($value)
{
return $this->coerceUrl($value);
}
/**
* @param $value
* @return float|null
*/
private function coerceUrl($value)
{ {
if (!is_string($value) || !filter_var($value, FILTER_VALIDATE_URL)) { // quite naive, but after all this is example if (!is_string($value) || !filter_var($value, FILTER_VALIDATE_URL)) { // quite naive, but after all this is example
throw new \UnexpectedValueException("Cannot represent value as URL: " . Utils::printSafe($value)); throw new \UnexpectedValueException("Cannot represent value as URL: " . Utils::printSafe($value));
@ -44,13 +42,22 @@ class UrlType extends ScalarType
} }
/** /**
* Parses an externally provided literal value to use as an input (e.g. in Query AST)
*
* @param $ast Node
* @return null|string * @return null|string
* @throws Error
*/ */
public function parseLiteral($ast) public function parseLiteral($ast)
{ {
if ($ast instanceof StringValue) { // Note: throwing GraphQL\Error\Error vs \UnexpectedValueException to benefit from GraphQL
// error location in query:
if (!($ast instanceof StringValue)) {
throw new Error('Query error: Can only parse strings got: ' . $ast->kind, [$ast]);
}
if (!is_string($ast->value) || !filter_var($ast->value, FILTER_VALIDATE_URL)) {
throw new Error('Query error: Not a valid URL', [$ast]);
}
return $ast->value; return $ast->value;
} }
return null;
}
} }