Skip to content

Commit 01bb04f

Browse files
committed
Implement ScalarType example: Email
1 parent ed7155e commit 01bb04f

File tree

8 files changed

+82
-10
lines changed

8 files changed

+82
-10
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"require": {
2020
"php": "^8.4",
2121
"ext-ctype": "*",
22+
"ext-filter": "*",
2223
"ext-iconv": "*",
2324
"ext-sqlite3": "*",
2425
"guzzlehttp/psr7": "^2.7.1",

composer.lock

Lines changed: 5 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Domain/Author/Author.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@
1717
public function __construct(
1818
public string $id,
1919
public string $name,
20-
public ?string $email,
20+
public ?Email $email,
2121
) {}
2222
}

src/Domain/Author/Email.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Jerowork\ExampleApplicationGraphqlAttributeSchema\Domain\Author;
6+
7+
use InvalidArgumentException;
8+
use Stringable;
9+
10+
final readonly class Email implements Stringable
11+
{
12+
public function __construct(
13+
public string $email,
14+
) {
15+
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
16+
throw new InvalidArgumentException('Invalid email address');
17+
}
18+
}
19+
20+
public function __toString(): string
21+
{
22+
return $this->email;
23+
}
24+
}

src/Infrastructure/Api/Http/GraphQL/Resolver/Mutation/CreateAuthorMutation.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Jerowork\ExampleApplicationGraphqlAttributeSchema\Domain\Author\Author;
88
use Jerowork\ExampleApplicationGraphqlAttributeSchema\Domain\Author\AuthorRepository;
9+
use Jerowork\ExampleApplicationGraphqlAttributeSchema\Domain\Author\Email;
910
use Jerowork\ExampleApplicationGraphqlAttributeSchema\Infrastructure\Api\Http\GraphQL\Type\AuthorType;
1011
use Jerowork\GraphqlAttributeSchema\Attribute\Mutation;
1112
use Ramsey\Uuid\Uuid;
@@ -19,7 +20,7 @@ public function __construct(
1920
) {}
2021

2122
#[Mutation(description: 'Create an author')]
22-
public function createAuthor(string $name, ?string $email): AuthorType
23+
public function createAuthor(string $name, ?Email $email): AuthorType
2324
{
2425
$author = new Author(
2526
(string) Uuid::uuid7(),

src/Infrastructure/Api/Http/GraphQL/Type/AuthorType.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Jerowork\ExampleApplicationGraphqlAttributeSchema\Infrastructure\Api\Http\GraphQL\Type;
66

77
use Jerowork\ExampleApplicationGraphqlAttributeSchema\Domain\Author\Author;
8+
use Jerowork\ExampleApplicationGraphqlAttributeSchema\Domain\Author\Email;
89
use Jerowork\GraphqlAttributeSchema\Attribute\Field;
910
use Jerowork\GraphqlAttributeSchema\Attribute\Type;
1011
use Symfony\Component\DependencyInjection\Attribute\Exclude;
@@ -30,7 +31,7 @@ public function getName(): string
3031
}
3132

3233
#[Field]
33-
public function getEmail(): ?string
34+
public function getEmail(): ?Email
3435
{
3536
return $this->author->email;
3637
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Jerowork\ExampleApplicationGraphqlAttributeSchema\Infrastructure\Api\Http\GraphQL\Type\Scalar;
6+
7+
use GraphQL\Language\AST\Node;
8+
use GraphQL\Language\AST\StringValueNode;
9+
use GraphQL\Type\Definition\ScalarType;
10+
use InvalidArgumentException;
11+
use Jerowork\ExampleApplicationGraphqlAttributeSchema\Domain\Author\Email;
12+
use Jerowork\GraphqlAttributeSchema\Attribute\Scalar;
13+
14+
#[Scalar(alias: Email::class)]
15+
final class EmailType extends ScalarType
16+
{
17+
public function serialize($value): string
18+
{
19+
if (!$value instanceof Email) {
20+
throw new InvalidArgumentException('Expected an Email value for custom scalar EmailType');
21+
}
22+
23+
return (string) $value;
24+
}
25+
26+
public function parseValue($value): Email
27+
{
28+
if (!is_string($value)) {
29+
throw new InvalidArgumentException('Expected a string value for custom scalar EmailType');
30+
}
31+
32+
return new Email($value);
33+
}
34+
35+
public function parseLiteral(Node $valueNode, ?array $variables = null): Email
36+
{
37+
if (!$valueNode instanceof StringValueNode) {
38+
throw new InvalidArgumentException('Expected a string value (node) for custom scalar EmailType');
39+
}
40+
41+
return new Email($valueNode->value);
42+
}
43+
}

src/Infrastructure/Persistence/Author/SQLite/SQLiteAuthorRepository.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Jerowork\ExampleApplicationGraphqlAttributeSchema\Domain\Author\Author;
88
use Jerowork\ExampleApplicationGraphqlAttributeSchema\Domain\Author\AuthorRepository;
9+
use Jerowork\ExampleApplicationGraphqlAttributeSchema\Domain\Author\Email;
910
use Jerowork\ExampleApplicationGraphqlAttributeSchema\Infrastructure\Persistence\SQLite\SQLiteFactory;
1011
use RuntimeException;
1112
use Symfony\Component\DependencyInjection\Attribute\AsAlias;
@@ -57,7 +58,7 @@ public function getById(string $authorId): Author
5758
return new Author(
5859
$row['id'],
5960
$row['name'],
60-
$row['email'],
61+
$row['email'] !== null ? new Email($row['email']) : null,
6162
);
6263
}
6364

@@ -109,7 +110,7 @@ public function getByIds(string ...$authorIds): array
109110
$authors[] = new Author(
110111
$row['id'],
111112
$row['name'],
112-
$row['email'],
113+
$row['email'] !== null ? new Email($row['email']) : null,
113114
);
114115
}
115116

@@ -156,7 +157,7 @@ public function save(Author $author): void
156157
$statement->bindValue('name', $author->name);
157158

158159
if ($author->email !== null) {
159-
$statement->bindValue('email', $author->email);
160+
$statement->bindValue('email', (string) $author->email);
160161
}
161162

162163
$statement->execute();

0 commit comments

Comments
 (0)