Skip to content

Instantly share code, notes, and snippets.

@abdullahseba
Created September 6, 2021 22:56
Show Gist options
  • Save abdullahseba/0e2cb2a8598eba0f44b736806d599e68 to your computer and use it in GitHub Desktop.
Save abdullahseba/0e2cb2a8598eba0f44b736806d599e68 to your computer and use it in GitHub Desktop.
GraphQL Custom Scalar Test Case
<?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' => 'test@test.com'
],
'users' => [
[
'userName' => 'test_user1',
'email' => 'test1@test.com'
],
[
'userName' => 'test_user2',
'email' => 'test2@test.com'
]
]
];
$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