Laravel Lighthouseがでサンプルで提供するスキーマにDateTime
型があります。DateTime
型はPHPのクラスと@scale
を通してマッピングされています。
スカラ型の定義
スカラ型のマッピングは*.graphqlファイルで、以下のように定義できます。
"A datetime string with format `Y-m-d H:i:s`, e.g. `2018-05-23 13:43:32`."
scalar DateTime @scalar(class: "Nuwave\\Lighthouse\\Schema\\Types\\Scalars\\DateTime")
オブジェクト型
定義したスカラ型は、オブジェクト型などの定義において以下のような形で利用できます。
type User {
id: ID!
name: String!
email: String!
email_verified_at: DateTime
created_at: DateTime!
updated_at: DateTime!
}
PHPでのクラス定義
マッピングされたPHPのクラス定義です。
format()
がCarbonからstringへの変換、parse()
がstringからCarbonへの変換です。
<?php
namespace Nuwave\Lighthouse\Schema\Types\Scalars;
use Illuminate\Support\Carbon;
class DateTime extends DateScalar
{
protected function format(Carbon $carbon): string
{
return $carbon->toDateTimeString();
}
protected function parse($value): Carbon
{
// @phpstan-ignore-next-line We know the format to be good, so this can never return `false`
return Carbon::createFromFormat(Carbon::DEFAULT_TO_STRING_FORMAT, $value);
}
}
DateTimeの継承関係
これは、GraphQL\Type\Definition\DateScalar
を継承しており、さらに下記の継承関係になっています。
- Nuwave\Lighthouse\Schema\Types\Scalars
- GraphQL\Type\Definition\DateScalar
- abstract class GraphQL\Type\Definition\ScalarType
- abstract class GraphQL\Type\Definition\Type
- interface JsonSerializable
- abstract class GraphQL\Type\Definition\Type
- abstract class GraphQL\Type\Definition\ScalarType
- GraphQL\Type\Definition\DateScalar
カスタム型定義はScalarTypeを継承する必要があり、継承先はJsonSerializableが要求するjsonSerialize()
を実装する必要があります。
ちなみにDateTimeの場合ですと、jsonSerialize()
はDateScalarの階層で実装しています。
jsonSerialize()の実装方法
jsonSerialize()をどのような形で実装すべきかは、ScalarTypeのPHPDocコメントに説明があります。
/**
* Scalar Type Definition
*
* The leaf values of any request and input values to arguments are
* Scalars (or Enums) and are defined with a name and a series of coercion
* functions used to ensure validity.
*
* Example:
*
* class OddType extends ScalarType
* {
* public $name = 'Odd',
* public function serialize($value)
* {
* return $value % 2 === 1 ? $value : null;
* }
* }
*/
abstract class ScalarType extends Type implements OutputType, InputType, LeafType, NullableType, NamedType
{
/** @var ScalarTypeDefinitionNode|null */
public $astNode;
/** @var ScalarTypeExtensionNode[] */
public $extensionASTNodes;
/**
* @param mixed[] $config
*/
public function __construct(array $config = [])
{
$this->name = $config['name'] ?? $this->tryInferName();
$this->description = $config['description'] ?? $this->description;
$this->astNode = $config['astNode'] ?? null;
$this->extensionASTNodes = $config['extensionASTNodes'] ?? null;
$this->config = $config;
Utils::invariant(is_string($this->name), 'Must provide name.');
}
}
こちらもおススメ