GraphQL,  Kotlin,  Ktor

Kotlin > Ktor > graphql-kotlin

Table of Content

ExpediaGroupが開発メンテしている、graphql-kotlinを、Ktorで試しました。

graphql-kotlinを、Ktorで動作するサンプルが、2020/12に追加された ようです。
https://github.com/ExpediaGroup/graphql-kotlin/tree/master/examples/server/ktor-server

今回は、追加されたExampleを、新規プロジェクトを作成しながらKtor-serverが動くようにしてみます。

新規プロジェクトを作成

Generate Ktor projectで新規プロジェクトを作成します
※ IntelliJでも新規プロジェクトは作れますが、obsolete(廃止)になっているので非推奨のようです。

graphql-kotlinは、Jacksonを使用しているので、
プラグインでJacksonを選択して、Generate projectを押します。

アプリケーションの雛形がZIPファイルで作られてダウンロードが始まります。

アプリケーション

ダウンロードしたファイルを解凍して、フォルダをIntellJで開きます。
以下のような構成になっていると思います。

参照の追加

build.gradle.kts に以下を追加します

val graphql_kotlin_server_version: String by project

dependencies {
    ...
    implementation("com.expediagroup:graphql-kotlin-server:$graphql_kotlin_server_version")
}

gradle.properties に以下を追加します

graphql_kotlin_server_version=4.1.1

ファイルの移植

Exampleからファイルを移植(コピー)します。
graphql-kotlin/examples/server/ktor-server/

以下のファイルをコピーします。

AuthorizedContext
GraphQLModule.kt
KtorDataLoaderRegistryFactory
KtorGraphQLContextFactory
KtorGraphQLRequestParser
ktorGraphQLSchema.kt
KtorGraphQLServer.kt
KtorServer
/schemaフォルダ
/resources/graphql-playground.html

フォルダ構成を変更して以下のように配置します。

├── Application.kt
├── graphqlkotlin
│   ├── AuthorizedContext.kt
│   ├── KtorDataLoaderRegistryFactory.kt
│   ├── KtorGraphQLContextFactory.kt
│   ├── KtorGraphQLRequestParser.kt
│   ├── KtorGraphQLServer.kt
│   ├── KtorServer.kt
│   └── ktorGraphQLSchema.kt
├── plugins
│   ├── GraphQLModule.kt
│   ├── Routing.kt
│   └── Serialization.kt
└── schema

Application.moduleに参照追加

Application.modulegraphQLModuleの呼び出しを追加します。

Application.kt

fun Application.module() {
    configureSerialization()
    configureRouting()
    graphQLModule() // Graph QL
}

resourcesにplaygroundファイル追加

resources/graphql-playground.htmlにファイルをコピーするのも忘れずに

SchemaGeneratorConfig

SchemaGeneratorConfigでPackage名を使っている箇所を変更します。
アプリケーションのPackage名に適宜変更します。

/graphqlkotlin/ktorGraphQLSchema.kt

private val config = SchemaGeneratorConfig(supportedPackages = listOf("com.expediagroup.graphql.examples.server.ktor"))
 ↓
private val config = SchemaGeneratorConfig(supportedPackages = listOf("com.example"))

動作確認

以上で動作するようになると思います。

実行して試してみましょう

起動したら以下にアクセスします。

http://localhost:8080/playground

画面が開いたら左側にQueryを入れてみます。

{
  hello
}

以下のような応答があれば成功です。

{
  "data": {
    "hello": "World!"
  }
}

より複雑なQueryでテストしてみます。

query {
  searchCourses(params: { ids: [1,2,3] }) {
    id
    name
    books {
      title
    }
    university {
      id
      name
    }
  }

  searchUniversities(params: { ids: [1]}) {
    id
    name
  }
}

以下のような応答が返ってくると思います

{
  "data": {
    "searchCourses": [
      {
        "id": 1,
        "name": "Biology 101",
        "books": [
          {
            "title": "Campbell Biology"
          },
          {
            "title": "The Cell"
          }
        ],
        "university": {
          "id": 1,
          "name": "University of Nebraska-Lincoln"
        }
      },
      {
        "id": 2,
        "name": "Cultural Anthropology",
        "books": [],
        "university": {
          "id": 1,
          "name": "University of Nebraska-Lincoln"
        }
      },
      {
        "id": 3,
        "name": "Computer Science 101",
        "books": [
          {
            "title": "Data Structures in C++"
          },
          {
            "title": "The Algorithm Design Manual"
          }
        ],
        "university": {
          "id": 1,
          "name": "University of Nebraska-Lincoln"
        }
      }
    ],
    "searchUniversities": [
      {
        "id": 1,
        "name": "University of Nebraska-Lincoln"
      }
    ]
  }
}

まとめ

今回は以上です。
ざっくりと、Ktorで動作するしくみがわかったと思います。
実際のプロダクトに組み込むには工夫が必要と思いますが、構成さえわかってしまえばなんとかなるかなと思います。
また、ソースファイルには、Apache License, Version 2.0 の記載があるので、利用の際にはご留意ください。

動かすまでのソースが多いので、KGraphQL の方が簡単かなという印象も持ちました。

KGraphQLを始めるStep1については以下に記載しています。
Kotlin > Ktor > KGraphQL Tutorial 1st Step