LoginSignup
5

More than 3 years have passed since last update.

posted at

updated at

Laravel 5.7 + GraphQL(Relation編)

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

今回はGraphQLでリレーションのデータを取得する方法をご紹介します。

シリーズ記事

記事のモデル、マイグレーション、ファクトリを作る

$ php artisan make:model -mf Post

GraphQLを使うのでコントローラは作りません。
ユーザーのモデルとシーダーに記事リレーションを修正します。

$ php artisan migrate:fresh --seed

マイグレーション&シーディングを実行する。
これは本題ではないのでコミットを参照ください。

1対多のリレーションデータを取得の例

PostTypeのGraphQL独自型の定義

$ php artisan make:graphql:type PostType

config/graphql.php

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

PostType を登録します。

app/GraphQL/Type/PostType.php

<?php

declare(strict_types = 1);

namespace App\GraphQL\Type;

use GraphQL\Type\Definition\Type;
use Folklore\GraphQL\Support\Type as BaseType;
use GraphQL;

class PostType extends BaseType
{
    protected $attributes = [
        'name' => 'PostType',
        'description' => 'post type'
    ];

    public function fields() : array
    {
        return [
            'id' => [
                'type' => Type::id(),
                'description' => 'The id of the user'
            ],
            'title' => [
                'type' => Type::string(),
                'description' => 'The title of post',
            ],
            'content' => [
                'type' => Type::string(),
                'description' => 'The content of post',
            ],
        ];
    }
}

PostType GraphQL独自型のfieldsを定義します。

app/GraphQL/Type/UserType.php

    public function fields() : array
    {
        return [
            'posts' => [
                'type' => Type::listOf(GraphQL::type('PostType')),
                'description' => 'The posts of user',
            ],
        ];
    }

1対多 動作確認

{
  user(id: 1) {
    id
    name
    posts {
      title
      content
    }
  }
}

posts { ... } と書いてあげるだけでリレーションデータを引っ張ってきてくれます!

{
  "data": {
    "user": {
      "id": "1",
      "name": "Prof. Mozell Beer",
      "posts": [
        {
          "title": "Nihil in autem autem molestiae.",
          "content": "Quod dolores sunt aspernatur voluptatem officia aut voluptatum. In dolores non dolore ut nesciunt voluptatem laboriosam. Pariatur aut et tenetur dolor doloribus."
        },
        {
          "title": "Dolores tenetur deserunt velit qui et in minus velit.",
          "content": "Quaerat sint excepturi dicta ut maiores. Est corporis expedita aut rerum sapiente. Explicabo hic dolorem nulla animi delectus voluptatem."
        },
        {
          "title": "Quia nostrum sapiente accusamus qui saepe.",
          "content": "Debitis praesentium autem est doloribus eius saepe. Iste dolorum consectetur incidunt ea aliquid et voluptas aut. Dignissimos sed autem eius adipisci. Eligendi eius pariatur aut earum."
        },
        {
          "title": "Quaerat corrupti inventore consectetur ipsam blanditiis.",
          "content": "Ad facere non officia commodi earum. Officiis deleniti itaque occaecati qui natus et. Fuga molestias alias atque adipisci. Itaque id praesentium ea."
        },
        {
          "title": "Nihil a illum magnam.",
          "content": "A quis deleniti quia quasi odio. Quas qui odit placeat sit tempora nulla voluptas. Consequatur nemo sit consequatur enim ratione."
        },
        {
          "title": "Aut tempore aut et enim.",
          "content": "Provident qui velit magni et. Molestiae qui dignissimos assumenda voluptas excepturi magnam ut. Nesciunt odit atque repudiandae ex delectus quia numquam."
        },
        {
          "title": "Beatae ipsa dignissimos eveniet officia eveniet explicabo.",
          "content": "Soluta expedita aut sit tempore. Et perferendis nemo culpa sit velit voluptatum. Quis natus iusto aut consectetur ex. Error voluptates ut quam. Ut molestias incidunt nihil rerum et itaque blanditiis."
        },
        {
          "title": "Quo non labore vel neque.",
          "content": "Officiis recusandae sunt ullam sit eos. Aspernatur architecto repellendus aut aliquid natus. Iusto praesentium perspiciatis veritatis sit ratione sequi."
        },
        {
          "title": "Dignissimos quia est fugit omnis sit dolores alias.",
          "content": "Non maiores nesciunt adipisci. Est aut distinctio soluta ducimus sed. Harum labore ut voluptas ea qui."
        },
        {
          "title": "Minus asperiores dolorem provident quo.",
          "content": "Voluptas ut odio qui eum totam sed neque. Necessitatibus excepturi eius quas iure. Quia enim voluptatem est molestiae non. Tenetur similique ullam qui iure enim voluptates voluptatem."
        }
      ]
    }
  }
}

こんな感じでリレーションデータを取得できます。
これの凄いところは、定義を追加しただけでライブラリ側で判断してユーザーが投稿した記事の情報を取得できているところです。

1対多 (Inverse)のリレーションデータを取得の例

記事のQueryを作る

$ php artisan make:graphql:query PostQuery
$ php artisan make:graphql:query PostsQuery

app/GraphQL/Type/PostType.php

    public function fields() : array
    {
        return [
            'user' => [
                'type' => GraphQL::type('UserType'),
                'description' => 'The user of post',
            ],
        ];
    }

1対多 (Inverse)の設定はこれだけです。

1対多 (Inverse) 動作確認

{
  post(id: 123) {
    id
    title
    user {
      id
      name
    }
  }
}

user { ... } と書いてあげるだけでリレーションデータを引っ張ってきてくれます!

{
  "data": {
    "post": {
      "title": "Quae itaque maxime sit eius ducimus qui quas.",
      "user": {
        "id": "13",
        "name": "Melany Johnson"
      }
    }
  }
}

とても簡潔に記述できます。

リレーションデータ取得処理のカスタマイズ

app/GraphQL/Type/PostType.php

    /**
     * ユーザー
     *
     * @param Post $root
     * @param array $args
     * @return User
     */
    protected function resolveUserField(Post $root, array $args) : User
    {
        logger('test');
        return $root->user;
    }

resolveフィールド名Field resolver関数を用意すればリレーションデータを取得する前に処理を差し込むことができます。
とても柔軟に対応できるので素敵だなぁと思いました。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
5