GraphQLの知識ゼロのやつが２週間GraphQLサーバーの開発を経験したのでまとめてみる

# この記事について

Qiita初投稿です。　
普段はWeb系エンジニアとして働いている筆者が業務にて、Ktorを使いGraphQLサーバーの立ち上げを実装することになったのでその経験をまとめました。
GraphQLってなに？という人がなんとなく概要を掴めるようになってもらえれば幸いです。

※ 実装の部分は一切解説していません。需要があれば別で記事を書きます。

# GraphQLについて

一言で言うと、RESTのようなAPIの規格のことです。
SQLのようなクエリ形式の言語でサーバーに問い合わせを行います。
Facebook社が開発したようで、現在はOSS化されています。[公式サイト](https://graphql.org/learn/)

**RESTと大きく違う点**

- 一度の通信で複数のデータの必要なプロパティだけ取得できる。　　
- エンドポイントは基本的に一つだけ。

### 簡単な仕組み

<img width="967" alt="スクリーンショット 2019-02-13 23.50.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/297968/3d9bf50f-6731-e218-e4e5-1253fab8854c.png">

クライアント: GraphQLのクエリで処理とレスポンスのデータを指定してサーバーに問い合わせる。
GraphQlサーバー: クエリを解釈して指定の処理を実行した後、指定されたデータをレスポンスとして返す。

### クエリーとミューテーション

GraphQLでは操作の種類が２種類あります。

`Query`　→　副作用を起こさないもの
`Mutation`　→　副作用を起こすもの

RESTと比較すると以下のようになります。

| GraphQL  | REST              |
|:--------:|:-----------------:|
| Query    | GET               |
| Mutation | POST, PUT, DELETE |


### http通信としてのリクエスト

実際にhttpの通信としてリクエストを送る時には `POST` で通信します。
パラメータとなるJsonデータは以下のような形式になります。

``` 
{
    “query” : “ ${GraphQLのクエリを書く} ”,
    “operationName” : “${実行するオペレーションをする}”,
    “variables” : “${クエリ内で使った変数の中身をJsonで定義する}”
}
```

# 文法について
GraphQLを使った通信では、サーバー側にスキーマを定義しておき、クライアント側はそのスキーマに従ってクエリを発行します。
ここでは、その文法を簡単に紹介します。
もっと詳しく知りたい方は公式のリファレンスや、他の記事を参照ください。
こちらの記事は大変勉強になりました。 → https://qiita.com/syu_chan_1005/items/3350f1d12c17a77e98c7

## スキーマ
サーバー側で定義するものです。

- どんなデータ構造なのか？
- どんなデータ処理なのか？

の２点を定義します。
実装自体はそれぞれのライブラリに依存すると思いますが、 `.graph` という形式のファイルにこれらの定義を記載します。 

###  データ構造

データの構造を型として定義します。
プリミティブ型は全部で５種類だそうです。

- `ID`
- `Boolean`
- `String`
- `Int`
- `Float`

これらを元にデータ型を定義します。
また、GraphQLではnullableも区別をします。

- `Int!` → `null` だと NG
- `Int` → `null` でも OK

以下サンプルです。

```
# type →　オリジナルの型の定義
type User {
	id: ID
	name: String
	email: String
	age: Int
}


# input型 → 操作の引数として使われる型
input UserInput {
	name: String! # null は NG
	email: String # null は OK
	age: Int!     # null は NG
}

```

非常にわかりやすいですね:blush:

型の種類は `enum` など、ほかにも様々な物があるようです。

### データ処理

型を定義したらそれらを使ってどのような操作をするかを定義します。

```
# Queryとして操作できる
# IDを指定することでUser型のデータを取得できる。
type Query {
    getUser(id: ID): User
}

# Mutationとして操作できる
# UserInput型のデータを入れるとcreateUserができて、Booleanが返ってくる
type Mutation {
    createUser(user: UserInput!): Boolean
}
```

`Query` と `Mutation` はそれぞれ `type` として定義できるようです。

## クエリ
クライアント側で発行するものです。
サーバー側ですでに定義されているスキーマを元に自身が必要なデータを取得するクエリを発行します。
`Query` と `Mutation` それぞれを定義する必要があります。

### Query

**Queryの定義** 

```
# User.id が １ のデータの name と age を取得する
query {
    getUser(id: “1”) {
        name
        age
    }
}
```

### Mutation

**Mutationの定義**

```
mutation create($inputUser: User!) {
　　　　createUser(user: $inputUser)
}
```

**Mutationで使用するvariables（Jsonで定義する）**

```
{
    “inputUser” : {
        “name” : "ほげ太郎”
        “email”: “sample@qiita.com”
        “age”: “3”
    }
}
```

# 試してみる

GitHubのV4系のAPIはGraphQLで問い合わせをすることができます。
ブラウザ上からも試すことができます。 → [ためしてみる](https://developer.github.com/v4/explorer/)

アクセスすると以下のようなページに遷移します。

<img width="1624" alt="スクリーンショット 2019-02-06 22.08.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/297968/f2dc6d98-c5d5-8831-7a2b-3d670efac8d3.png">

左上側のテキストボックスにクエリを書いて実行すると、右側にレスポンスのJsonが表示されます。
（きちんと指定した形式でデータが返ってきているのが確認できますね:muscle:）

一番右側ではスキーマの定義を確認することができます。

Mutationなどの操作で変数を使用する場合は左下の `QUERY VARIABLES` にJsonで記載してください。
※Variablesを使わない場合でも空のJsonデータを入力しないとエラーになると思います。

実際に開発する場合は [GraphiQL](https://electronjs.org/apps/graphiql) というツールを使うことをおすすめします:thumbsup:

# おわりに

拙い記事を最後まで読んでくださりありがとうございました。
少しでもあなたのためになったら幸いです。