Laravel Lighthouseのスカラ型をPHPのクラスにマッピングする

カテゴリ: 未分類 | タグ: , , , ,

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

カスタム型定義は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.');
    }
}

Amazonでおトクに買い物する方法
AmazonチャージでポイントGET


Amazonは買いもの前にAmazonギフト券をチャージしてポイントをゲットしないと損!

こちらもおススメ

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です