Kotlin,  Ktor

Kotlin > Ktor > KGraphQL Basic Example

Table of Content

Kotlin > Ktor > KGraphQL Basic Example

KGraphQLのExamplesにのっている、Basic Exampleを試してみました。

KGraphQLで扱うType

Operations - KGraphQL
に書いてある通り、基本は、3つのタイプがあります。

  • Query: 読み取り専用フェッチ。
  • Mutation: 書き込みとそれに続くフェッチ。
  • Subscription: スイベントに応答してデータをフェッチする長期的なリクエスト。(まだサポートされていません。)

各操作はSchemaBuilderブロックで宣言されます。
また、すべての操作には2つのプロパティがあります。

  • name: 操作名
  • resolver: Resolver(応答値、応答方法)

実行

GithubからソースをCloneしてきて、
KGraphQL/kgraphql-example at main · aPureBase/KGraphQL

kgraphql-exampleモジュールをRunします。

query

Basic Exampleには以下のようなqueryがありました。

  • sightings
  • sighting
  • user
  • topSightings
  • topCountrySightings

それぞれ実行して、応答値を確認することで、処理の流れを俯瞰してみます。

sightings

UFO Sightingレコードのサブセットを返します。

query定義

query("sightings") {
    resolver { size: Int? -> service.findAll(size ?: 10).toMutableList() }.withArgs {
        arg<Int> { name = "size"; defaultValue = 10; description = "The number of records to return" }
    }
}

QraphQL Query

{
  sightings(size: 2){
    id
    dateSighting
    city
    state
    country
    shape
    duration
    comments
    latitude
    longitude
  }
}

result

{
  "data" : {
    "sightings" : [ {
      "id" : 2,
      "dateSighting" : "2013-01-01",
      "city" : "norwich (uk/england)",
      "state" : "",
      "country" : "",
      "shape" : "oval",
      "duration" : 40.0,
      "comments" : "These were real alien craft and very fast and able to stop and make clever formations; fantastic to see.",
      "latitude" : 52.633333,
      "longitude" : 1.3
    }, {
      "id" : 3,
      "dateSighting" : "2013-01-01",
      "city" : "richmond",
      "state" : "va",
      "country" : "",
      "shape" : "triangle",
      "duration" : 300.0,
      "comments" : "Orange lights over Richmond va/ d..c.",
      "latitude" : 37.5536111,
      "longitude" : -77.4605556
    } ]
  }
}

sighting

指定するidに一致するレコードを返します。

query定義

query("sighting") {
    resolver { id: Int ->
        service.findById(id) ?: throw NotFoundException("Sighting with id: $id does not exist")
    }
}

QraphQL Query

{
  sighting(id: 1){
    id
    dateSighting
    latitude
    longitude
  }
}

result

{
  "data": {
    "sighting": {
      "id": 1,
      "dateSighting": "2013-01-01",
      "latitude": 48.7597222,
      "longitude": -122.4869444
    }
  }
}

user

idまたは認証されたユーザーを返します。

query定義

query("user") {
    resolver { ctx: Context, id: Int? ->
        if (id == null) {
            User(4, ctx.get<User>()?.name ?: throw NotAuthenticatedException())
        } else {
            users.getOrNull(id - 1) ?: throw NotFoundException("User with id: $id does not exist")
        }
    }
}

QraphQL Query

{
  user(id: 1){
      id
      name
  }
}

result

{
  "data": {
    "user": {
      "id": 1,
      "name": "Amber"
    }
  }
}

topSightings

UFOの目撃数の多い州、国のリストを返す

query定義

query("topSightings") {
    resolver { -> service.getTopSightings() }
}

QraphQL Query

{
  topSightings{
    state
    country
    numOccurrences
  }
}

result

{
  "data": {
    "topSightings": [
      {
        "state": "ca",
        "country": "us",
        "numOccurrences": 887
      },
      {
        "state": "fl",
        "country": "us",
        "numOccurrences": 677
      },
      {
        "state": "oh",
        "country": "us",
        "numOccurrences": 380
      },
      {
        "state": "wa",
        "country": "us",
        "numOccurrences": 378
      },
以下略

topCountrySightings

UFOの目撃数が上位の国のリストを返します。

query定義

query("topCountrySightings") {
    resolver { -> service.getTopCountrySightings() }
}

QraphQL Query

{
  topCountrySightings{
    country
    numOccurrences
  }
}

result

{
  "data": {
    "topCountrySightings": [
      {
        "country": "us",
        "numOccurrences": 8021
      },
      {
        "country": "",
        "numOccurrences": 860
      },
      {
        "country": "ca",
        "numOccurrences": 293
      },
      {
        "country": "gb",
        "numOccurrences": 69
      },
      {
        "country": "au",
        "numOccurrences": 46
      },
      {
        "country": "de",
        "numOccurrences": 9
      }
    ]
  }
}

schemaの確認

QraphQL Query

{ 
  __schema {
    types {
        name
        description,
        fields {
            name
            description
        }
    }
    }
}

複数のQuery

user==1と、UFOの目撃数が上位の国のリストを返します。

{
  user(id: 1){
      id
      name
  }
  topCountrySightings{
    country
    numOccurrences
  }
}

mutation

createUFOSighting

新しいUFO Sightingをデータベースに追加します。

query定義

mutation("createUFOSighting") {
    resolver { input: CreateUFOSightingInput ->
        service.create(input.toUFOSighting())
    }
}

QraphQL mutation

mutation createUFOSighting {
    createUFOSighting(
        input: {
            shape: "oval"
            country: [ 
                {
                    city: "norwich"
                    state: "va"
                    country: "us"
                    comments: "Orange lights over Richmond"
                }
            ]
        }
    ) {
        id
        country
    }
}

result

{
  "data": {
    "user": {
      "id": 1,
      "name": "Amber"
    }
  }
}

Subscription

まだサポートされていないとのことです。
今後に期待?

感想

全体を追いかけてみて、Basic Exampleという名の通り、
作り込まれているわけではなくて、全体の流れを把握するためのBasic Exampleというものみたいです。

一部動かないところもあったのでプルリクを出して修正してもらったりしました。
https://github.com/aPureBase/KGraphQL/issues/158
(プルリク出してからマージまで数時間だったので対応は早かったです。)

できることはなんとなく掴むことができました。