Laravel 5.7 + GraphQL（ScalarType編）

[LaravelとGraphQLでAPI開発](https://qiita.com/ucan-lab/items/b1796b083ac5c0bcb019)こちらの記事の続きです。

## シリーズ記事

- [LaravelとGraphQLでAPI開発](https://qiita.com/ucan-lab/items/b1796b083ac5c0bcb019)
- [Laravel 5.7 + GraphQL（Install編）](https://qiita.com/ucan-lab/items/32969d6a9b5aa99b475e)
- Laravel 5.7 + GraphQL（ScalarType編）
- [Laravel 5.7 + GraphQL（Relation編）](https://qiita.com/ucan-lab/items/4eae9e538be9a7a7c5e9)
- [Laravel 5.7 + GraphQL（Dump Server編）](https://qiita.com/ucan-lab/items/ce9abab3fddec0d2d0eb)
- [Laravel 5.7 + GraphQL（Pagination編）](https://qiita.com/ucan-lab/items/c037d4bd07840af32b94)
- [Laravel 5.7 + GraphQL（ErrorHandling編）](https://qiita.com/ucan-lab/items/fa3bf9b1e7fca1b19d0d)
- [Laravel 5.7 + GraphQL（Test編）](https://qiita.com/ucan-lab/items/1815071cd1cf32d53008)

## GraphQLのスカラー型

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

```shell-session
$ php artisan make:graphql:scalar DateTimeType
```

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

### app/GraphQL/Scalars/DateTimeType.php

```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

```php
    '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

```php
    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型のカラムを追加します。

## 動作確認

```graphql
{
  user {
    id
    name
    created_at
    updated_at
  }
}
```

queryを実行します。

```json
{
  "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

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

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

```graphql
{
  user {
    id
    name
    created_at
    updated_at
  }
}
```

同じqueryを発行します。

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

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