Kotlin > Ktor > KGraphQL Basic Example
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
(プルリク出してからマージまで数時間だったので対応は早かったです。)
できることはなんとなく掴むことができました。