Help us understand the problem. What is going on with this article?

Laravel 5.7 + GraphQL(ScalarType編)

More than 1 year has passed since last update.

LaravelとGraphQLでAPI開発こちらの記事の続きです。

シリーズ記事

GraphQLのスカラー型

Folkloreatelier/laravel-graphqlに標準で組み込まれているスカラー型はID、String、Int、Float、Booleanの5種類しかありません。
日付型(DateTime)をGraphQLで表示するために自分でカスタムスカラー型を定義します。

$ php artisan make:graphql:scalar DateTimeType

https://github.com/ucan-lab/practice-laravel-graphql/commit/833a3eeb71da5fcb2b59d55908fdab3a3917aa72

app/GraphQL/Scalars/DateTimeType.php

<?php

declare(strict_types = 1);

namespace App\GraphQL\Scalars;

use Folklore\GraphQL\Support\Contracts\TypeConvertible;
use GraphQL\Type\Definition\ScalarType;
use DateTime;

class DateTimeType extends ScalarType implements TypeConvertible
{
    /**
     * @var string
     */
    public $name = 'DateTimeType';

    /**
     * @var string
     */
    public $description = 'DateTime scalar type';

    /**
     * @param mixed $value
     * @return mixed
     */
    public function serialize($value) : DateTime
    {
        return $value;
    }

    /**
     * @param mixed $value
     * @return string
     */
    public function parseValue($value) : string
    {
        return $value;
    }

    /**
     * @param $ast
     * @return null|string
     */
    public function parseLiteral($ast) : ?string
    {
        return null;
    }

    /**
     * @return DateTimeType
     */
    public function toType() : DateTimeType
    {
        return new static();
    }
}

強い型付けを追加しただけで、コードの挙動はひな形のままです。

config/graphql.php

https://github.com/ucan-lab/practice-laravel-graphql/commit/4aad066ee53a091959e7c9ec3e04210c76c7be6b

    'types' => [
        App\GraphQL\Type\UserType::class,
        // custom scalar type
        App\GraphQL\Scalars\DateTimeType::class,
    ],

作成したスカラー型クラスを登録します。

app/GraphQL/Type/UserType.php

https://github.com/ucan-lab/practice-laravel-graphql/commit/d4de2b07a4819e5255fbdabd5341ad0ca6a4db43

    public function fields() : array
    {
        return [
            // ... 省略
            'created_at' => [
                'type' => GraphQL::type('DateTimeType'),
                'description' => 'The created_at of user',
            ],
            'updated_at' => [
                'type' => GraphQL::type('DateTimeType'),
                'description' => 'The updated_at of user',
            ],
        ];
    }

UserTypeクラスの fields 関数にDateTime型のカラムを追加します。

動作確認

{
  user {
    id
    name
    created_at
    updated_at
  }
}

queryを実行します。

{
  "data": {
    "user": {
      "id": "1",
      "name": "Maximus Bechtelar",
      "created_at": {
        "date": "2018-10-13 09:13:29.000000",
        "timezone_type": 3,
        "timezone": "UTC"
      },
      "updated_at": {
        "date": "2018-10-13 09:13:29.000000",
        "timezone_type": 3,
        "timezone": "UTC"
      }
    }
  }
}

とこんな感じでDateTimeの値を取得できます。

UnixTimeを返したい

app/GraphQL/Scalars/DateTimeType.php

    public function serialize($value) : int
    {
        return (int)$value->format('U');
    }

serialize関数で DateTime 型を返していたところを UnitTime に変換して int 型で返します。

{
  user {
    id
    name
    created_at
    updated_at
  }
}

同じqueryを発行します。

{
  "data": {
    "user": {
      "id": "1",
      "name": "Maximus Bechtelar",
      "created_at": 1539422009,
      "updated_at": 1539422009
    }
  }
}

UnixTime が返ってきます。
シンプルに書けて良き😊

ucan-lab
Backend Developer at ROLO. I love PHP and I'm focusing on Laravel, Docker, GraphQL.
https://u-can.pro
yyphp
PHPerが毎週集まり、ざっくばらんに情報交換する雑談コミュニティ
https://yyphp.connpass.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away