Kotlin > Ktor > KGraphQL Basic Example




KGraphQLの[Examples](https://kgraphql.io/Examples/)にのっている、Basic Exampleを試してみました。


## KGraphQLで扱うType


[Operations - KGraphQL](https://kgraphql.io/Reference/operations/#overview)
に書いてある通り、基本は、3つのタイプがあります。


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


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

- name: 操作名
- resolver: Resolver（応答値、応答方法）



# 実行


GithubからソースをCloneしてきて、
[KGraphQL/kgraphql-example at main · aPureBase/KGraphQL](https://github.com/aPureBase/KGraphQL/tree/main/kgraphql-example)

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


# query

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

- sightings
- sighting
- user
- topSightings
- topCountrySightings


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


### sightings

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

#### query定義

```Kotlin:GraphQLSchema.kt
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

```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定義

```Kotlin:GraphQLSchema.kt
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

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




### user


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

#### query定義

```Kotlin:GraphQLSchema.kt
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

```Javascript:result
{
  "data": {
    "user": {
      "id": 1,
      "name": "Amber"
    }
  }
}
```


### topSightings


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


query定義

```Kotlin:GraphQLSchema.kt
query("topSightings") {
    resolver { -> service.getTopSightings() }
}
```



#### QraphQL Query

```
{
  topSightings{
    state
    country
    numOccurrences
  }
}
```


#### result

```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定義

```Kotlin:GraphQLSchema.kt
query("topCountrySightings") {
    resolver { -> service.getTopCountrySightings() }
}
```



QraphQL Query

```
{
  topCountrySightings{
    country
    numOccurrences
  }
}
```


#### result

```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定義

```Kotlin:GraphQLSchema.kt
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

```Javascript:result
{
  "data": {
    "user": {
      "id": 1,
      "name": "Amber"
    }
  }
}
```



# Subscription

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


# 感想

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

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

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

[ExpediaGroup/graphql-kotlin](https://github.com/ExpediaGroup/graphql-kotlin)よりも簡単に使えそうな感じです。
Starの数の桁が違うのが悩みどころです