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を返却する部分について 実装をしていきたい。