Created
September 6, 2021 22:56
-
-
Save abdullahseba/0e2cb2a8598eba0f44b736806d599e68 to your computer and use it in GitHub Desktop.
GraphQL Custom Scalar Test Case
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
// Run local test server | |
// php -S localhost:8080 graphql.php | |
// Try query | |
// curl -d '{"query": "query { echo(message: \"Hello World\") }" }' -H "Content-Type: application/json" http://localhost:8080 | |
// Try mutation | |
// curl -d '{"query": "mutation { sum(x: 2, y: 2) }" }' -H "Content-Type: application/json" http://localhost:8080 | |
require_once __DIR__ . '/../../vendor/autoload.php'; | |
use GraphQL\GraphQL; | |
use GraphQL\Type\Definition\ObjectType; | |
use GraphQL\Type\Definition\Type; | |
use GraphQL\Type\Schema; | |
use GraphQL\Type\Definition\ScalarType; | |
use GraphQL\Type\Definition\CustomScalarType; | |
use GraphQL\Language\AST\StringValueNode; | |
use GraphQL\Utils\Utils; | |
use GraphQL\Error\DebugFlag; | |
use GraphQL\Language\Parser; | |
use GraphQL\Utils\SchemaExtender; | |
use GraphQL\Error\Error; | |
use GraphQL\Error\SerializationError; | |
use GraphQL\Language\AST\Node; | |
class EmailType extends ScalarType | |
{ | |
public function serialize($value): string | |
{ | |
error_log('true'); | |
if (!$this->isEmail($value)) { | |
throw new SerializationError('Cannot represent value as email: ' . Utils::printSafe($value)); | |
} | |
return $value; | |
} | |
public function parseValue($value): string | |
{ | |
if (!$this->isEmail($value)) { | |
throw new Error('Cannot represent value as email: ' . Utils::printSafe($value)); | |
} | |
return $value; | |
} | |
public function parseLiteral(Node $valueNode, ?array $variables = null): string | |
{ | |
// 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]); | |
} | |
$value = $valueNode->value; | |
if (!$this->isEmail($value)) { | |
throw new Error('Not a valid email', [$valueNode]); | |
} | |
return $value; | |
} | |
/** | |
* Is the value a valid email? | |
* | |
* @param mixed $value | |
*/ | |
private function isEmail($value): bool | |
{ | |
return filter_var($value, FILTER_VALIDATE_EMAIL) !== false; | |
} | |
} | |
$customEmailType = new CustomScalarType([ | |
'name' => 'Email', | |
'serialize' => static function ($value) { | |
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) { | |
throw new InvariantViolation("Could not serialize following value as email: " . Utils::printSafe($value)); | |
} | |
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) { | |
throw new Error("Cannot represent following value as email: " . Utils::printSafeJson($value)); | |
} | |
return $value; | |
}, | |
'parseValue' => static function ($value) { | |
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) { | |
throw new Error("Cannot represent following value as email: " . Utils::printSafeJson($value)); | |
} | |
return $value; | |
}, | |
'parseLiteral' => static function (Node $valueNode, ?array $variables = null) { | |
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; | |
}, | |
]); | |
try { | |
$emailType = new EmailType(); | |
//WORKS. | |
// $emailType = $customEmailType; | |
$userType = new ObjectType([ | |
'name' => 'User', | |
'fields' => [ | |
'userName' => Type::string(), | |
'email' => $emailType, | |
] | |
]); | |
$queryType = new ObjectType([ | |
'name' => 'Query', | |
'fields' => [ | |
'user' => [ | |
'type' => $userType, | |
], | |
], | |
]); | |
$gql = ' | |
extend type Query { | |
users: [User] | |
} | |
'; | |
$schema = new Schema([ | |
'query' => $queryType, | |
]); | |
$documentNode = Parser::parse($gql); | |
//COMMENT THIS OUT FOR EMAIL TO WORK. | |
$schema = SchemaExtender::extend($schema, $documentNode, []); | |
$rawInput = file_get_contents('php://input'); | |
$input = json_decode($rawInput, true); | |
$query = $input['query']; | |
$variableValues = $input['variables'] ?? null; | |
$debug = DebugFlag::INCLUDE_DEBUG_MESSAGE; | |
$rootValue = [ | |
'user' => [ | |
'userName' => 'test_user', | |
'email' => '[email protected]' | |
], | |
'users' => [ | |
[ | |
'userName' => 'test_user1', | |
'email' => '[email protected]' | |
], | |
[ | |
'userName' => 'test_user2', | |
'email' => '[email protected]' | |
] | |
] | |
]; | |
$result = GraphQL::executeQuery($schema, $query, $rootValue, null, $variableValues); | |
$output = $result->toArray($debug); | |
} catch (Throwable $e) { | |
$output = [ | |
'error' => [ | |
'message' => $e->getMessage(), | |
], | |
]; | |
} | |
header('Content-Type: application/json; charset=UTF-8'); | |
echo json_encode($output); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment