SpringBoot × KotlinでGraphQLに入門する

はじめに

GraphQLを理解するために、SpringBoot×Kotlinでためしてみることにした。

確認環境

確認する環境は以下で実施する。

開発環境

mac book pro

エディタ

intelij IDEA CM

ソフトウェア

  • Kotlin
  • SpringBoot(2.3.3)
  • Gradle
  • GraphQL Playground

環境構築

まずは環境構築。 雛形はspring initializrを使って作成する。 ここの手順は割愛する。

intelij IDEAのplugin

GraphQLのSchema定義を実装するのに便利なためJS GraphQLを導入する。 導入することでハイライトが効くようになる。

GraphQLの動作確認ツール

HomebrewでGraphQL Playgroundを導入する。

brew cask install graphql-playground

依存性の設定

まずはGraphQLのライブラリを使って実装をするため Gradleで設定を行う。 使うライブラリは以下の通り * GraphQL Java * GraphQL Spring Boot Starter * GraphQL Java Tools

implementation("com.graphql-java-kickstart:graphql-spring-boot-starter:5.7.3")
implementation("com.graphql-java-kickstart:altair-spring-boot-starter:5.7.3")
implementation("com.graphql-java-kickstart:graphiql-spring-boot-starter:5.7.3")
implementation("com.graphql-java-kickstart:voyager-spring-boot-starter:5.7.3")

GraphQLとは

以下を参照した。 https://ja.wikipedia.org/wiki/GraphQL

概要

概要は以下の感じだった。wikipediaから引用する。

GraphQLでは、クライアントが必要なデータの構造を定義することができ、サーバーからは定義したのと同じ構造のデータが返される。したがって、必要以上に大きなデータが返されるのを防ぐことができクエリの効率が良い。また、柔軟性と豊かな表現が可能なクエリ言語は複雑さを加えるため、シンプルなAPIには適さない可能性もある GraphQLは、型システム、クエリ言語、実行セマンティクス、静的な検証、型イントロスペクション(英語版)から構成される。 GraphQLはデータの読み込み/query、書き込み/mutation、購読/subscriptionをサポートする

もうちょっと詳しく

これも同じくwikipediaから引用

GraphQLでは、クライアントがクエリ内容を記したdocumentを送信し、GraphQLサービスがクエリを実行し結果を返信する。documentはDSLであるGraphQL query languageを用いて記述される。以下の例は明日の天気を取得するクエリのdocumentとGraphQLサービスから返されたクエリ結果のJSONである。

// document
{
  tomorrow {
    weather
    rainyPercent
  }
}
// response JSON
{
  "tomorrow": {
    "weather": "cloudy",
    "rainyPercent": 30
  }
}

さらに以下の記述があったこれでなんとなく、イメージがつかめた感がある。

リソースをURLパスで表現するRESTful APIと異なり、GraphQLはリソースをdocumentで表現する。GraphQL WebAPIの場合、単一のAPIエンドポイントへこのdocumentをPOSTする(例:https://API.internal./graphqlエンドポイントへdocumentをBodyとしてPOSTする)ことでクエリが実行される

掴んだイメージ

  • REST APIと同じく何らかのAPIである
  • クライアント側はPOSTでリクエストをする
  • そのリクエストの中にdocumentという要素があり、その中に欲しい情報を含める
  • API側はそのdocument情報にあった情報を返却するように処理を行う

実装

早速実装して動作を確認していく。

スキーマ定義を実装する

scheme.graphqlsを作成する このファイルはresource配下に配置しないとSpringBootの起動ができなかった。 (resource配下にある、*.graphqlsファイルの存在をチェックしているようだった。)

defaultが上記のようになっているようなので、これを設定する方法はあるかもしれない。 これを記載している時点では上記を確認していない。

この時点で定義したscheme.graphqlsは以下の通り。

type Book {
    id: String
    name: String
}
type Query {
    bookById(id: String): Book
}

Typeクラスを実装する

scheme.graphqlsで定義したBookクラスを実装する 今回は以下のように定義した。

package com.example.graphqlsample.graphql

data class Book(
        private val id: String,
        private val name: String
)

resolverを実装する

実際のデータ操作を行う処理がこのresolverとなる。 ここではBookResolverとする。

package com.example.graphqlsample.graphql

import com.coxautodev.graphql.tools.GraphQLQueryResolver
import org.springframework.stereotype.Component

@Component
class BookResolver: GraphQLQueryResolver {
    fun bookById(id: String): Book {
        return Book(
                id = id,
                name = "test"
        )
    }
}

ポイントは以下かなと。

  • @Componentをつける

  • GraphQLQueryResolverを継承する形で実装を行う

  • scheme.graphqlsのQueryに書いた定義をメソッドとして定義する。(ここではbookByIdメソッド)

動作確認

graphql-playgroundで動作確認を行う。 エンドポイントは以下を指定する。

http://localhost:8080/graphql

ここで指定するqueryを定義して実行する これがdocumentの送信にあたる。

query {
  bookById(id:"2") {
    id
    name
  }
}

結果

{
  "data": {
    "bookById": {
      "id": "2",
      "name": "test"
    }
  }
}

まとめ

SpringBoot × KotlinでGraphQLの実装をしてみた。 Controllerの実装をすることなく、APIが実装できた。 次はクライアント側の要求するものから柔軟にresponseを返却する部分について 実装をしていきたい。

参考