AppSyncでGraphQLを用いてDynamoDBを操作する

# はじめに

ある日自社アプリの IoT.kyoto VIS をServerlessでいい感じにリプレイスしたのを話したときに、アーキテクチャを見てもらった人から「APIの部分AppSyncでやらないの？」とアドバイス頂いたので、AppSyncを使ってGraphQLに入門しました。
この記事では簡単なGraphQLを使ってDynamoDBのデータを操作することを目標に手順を書いていきます。

## GraphQLとは

```
GraphQLはAPI用のクエリ言語であり、データ用に定義した型システムを使用してクエリを実行するためのサーバー側のランタイムです。
GraphQLは、特定のデータベースまたはストレージエンジンに結びついておらず、代わりに既存のコードとデータに基づいています。
```

引用: [https://graphql.org/learn/](https://graphql.org/learn/)

まぁ、RESTAPIの代わりになりそう！って感じのものです。

## AppSyncとは

```
AWS AppSync では、ウェブアプリケーションやモバイルアプリケーション内のデータがリアルタイムで自動的に更新されます。
また、オフラインユーザーが再接続するとすぐにデータが更新されます。AWS AppSync により、応答性に優れた協働的なユーザーエクスペリエンスを実現できる、
共同のモバイルアプリケーションやウェブアプリケーションを簡単に構築できます。

AWS AppSync を使用すると、iOS、Android、JavaScript、React Native を使ってネイティブなモバイルアプリケーションやウェブアプリケーションを
構築できます。
AWS AppSync コンソールにアクセスし、シンプルなコードステートメントでアプリケーションのデータを指定して、使用を開始してください。
アプリケーションのデータの保存、処理、取得に必要なものすべては、AWS AppSync で管理されます。
```

引用: [https://aws.amazon.com/jp/appsync/](https://aws.amazon.com/jp/appsync/)

AWSでGraphQL使うならAppSyncや。ってくらいに思っててください。

## 登場人物

AWSAppSyncには主にこんだけの登場人物が登場します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/95875/a90996f4-1515-5b93-872a-b5f76e10a2b2.png)

### API

定義されたGraphQLを呼び出すAPIの口。
呼び出すための設定ファイルが発行される。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/95875/3803881b-335f-a03d-bf1d-e48208286c00.png)

### Schema

GraphQLの定義。
APIや使用する要素の型定義などを設定する。

![AWS AppSync Console 2018-11-06 18-11-14.png](https://qiita-image-store.s3.amazonaws.com/0/95875/2ed18e42-8899-e682-a963-08769f618c4c.png)

### Resolvers

APIがどのような操作をするか定義する。

![AWS AppSync Console 2018-11-06 18-11-53.png](https://qiita-image-store.s3.amazonaws.com/0/95875/f69668da-93f5-7b50-84a6-df97716e283d.png)

## 今回のゴール

画像のようにDynamoDBにPutItemするところまでやっていきます。

![DynamoDB · AWS Console 2018-11-06 18-00-22.png](https://qiita-image-store.s3.amazonaws.com/0/95875/6d9c8566-0416-b477-2872-08b84d83c908.png)

## 作業開始！

### APIを作成

![AWS AppSync Console 2018-11-06 17-32-37.png](https://qiita-image-store.s3.amazonaws.com/0/95875/10b53ba5-88a1-0d4d-98b8-55d6886bcdf1.png)

![AWS AppSync Console 2018-11-06 17-35-03.png](https://qiita-image-store.s3.amazonaws.com/0/95875/d62f5f7d-9ad1-feba-3f01-0dd184d9326f.png)

![AWS AppSync Console 2018-11-06 17-36-36.png](https://qiita-image-store.s3.amazonaws.com/0/95875/90daf857-f4d7-e4a8-be7f-0b742dae80d0.png)

### Schemaを作成

![AWS AppSync Console 2018-11-06 17-37-52.png](https://qiita-image-store.s3.amazonaws.com/0/95875/79c0a7a8-5068-91ae-6ce8-f9056f7433bc.png)

先にDynamoDBテーブルを作成していきます。テーブル名を変えるだけで、その他はデフォルトの設定でテーブルを作成します。

![AWS AppSync Console 2018-11-06 17-39-15.png](https://qiita-image-store.s3.amazonaws.com/0/95875/a591a9a9-6695-8d2a-f946-70b1c53ebbd1.png)

![AWS AppSync Console 2018-11-06 17-44-59.png](https://qiita-image-store.s3.amazonaws.com/0/95875/888759f7-766c-85a5-1509-9984271039b1.png)

![AWS AppSync Console 2018-11-06 17-47-34.png](https://qiita-image-store.s3.amazonaws.com/0/95875/7a18b583-7109-ac82-dc4c-55c61999a97c.png)

![AWS AppSync Console 2018-11-06 17-45-29.png](https://qiita-image-store.s3.amazonaws.com/0/95875/516acc3d-1b97-97b3-c72c-c8fc3a828d59.png)

これでDynamoDBにテーブルが作成されます。
こんな感じでSchemaも自動生成されています。

![AWS AppSync Console 2018-11-06 17-51-36.png](https://qiita-image-store.s3.amazonaws.com/0/95875/7ca2d79c-a148-7c47-c3a4-e0dfc9078099.png)

## 実際にクエリを実行する

![AWS AppSync Console 2018-11-06 17-55-08.png](https://qiita-image-store.s3.amazonaws.com/0/95875/43ab5bc9-a2e7-7d27-b3f8-af76151fdb6a.png)

こういうコンソール画面が表示されます。左側がGraphQLを入力するエリアで、右側が実行した結果が表示されるエリアです。

![AWS AppSync Console 2018-11-06 17-56-35.png](https://qiita-image-store.s3.amazonaws.com/0/95875/8b52b9b1-88ee-63f9-536c-04788cf377f6.png)

アイテムをCreateしてみましょう。
Createするためには `createMyCustomType` というAPIを呼び出します。
上記のAPIをコールするためには何が必要なのでしょうか？
Schemaを確認してみると、

```
createMyCustomType(input: CreateMyCustomTypeInput!): MyCustomType
```

という記述がされています。
`input: CreateMyCustomTypeInput!` と書いているので、　`input` に何が必要なのでしょうか？ `CreateMyCustomTypeInput` を確認しましょう。

```
input CreateMyCustomTypeInput {
	title: String!
	content: String!
	price: Int
	rating: Float
}
```

と書いてあるので、 `title` と `content` が必須。型は `String` とのことなので、コンソール画面の左側に下記のテキスト貼り付けます。

```text

mutation create {
  createMyCustomType(input: {
    title: "テストタイトル"
    content: "テストですよよよ。"
  }) {
    id
    title
    content
  }
}
```

左上の実行ボタンをクリックすると、

```text

{
  "data": {
    "createMyCustomType": {
      "id": "2033baef-fb4e-4bf6-a155-f08775103994",
      "title": "テストタイトル",
      "content": "テストですよよよ。"
    }
  }
}
```

という実行結果が返ってきて、DynamoDBにアイテムがPutされています。

![DynamoDB · AWS Console 2018-11-06 18-00-22.png](https://qiita-image-store.s3.amazonaws.com/0/95875/6d9c8566-0416-b477-2872-08b84d83c908.png)

作成したアイテムを取得してみましょう。コンソール画面の左側に下記のテキスト貼り付けます。

```text

query list {
  listMyCustomTypes {
    items {
      id
      title
      content
    }
  }
}
```

同じように左上の実行ボタンをクリックすると、

```text

{
  "data": {
    "listMyCustomTypes": {
      "items": [
        {
          "id": "2033baef-fb4e-4bf6-a155-f08775103994",
          "title": "テストタイトル",
          "content": "テストですよよよ。"
        }
      ]
    }
  }
}
```

上記のような結果が返ってきて、作成したアイテムの情報が取得できます。
他にも下記のAPIが用意されているので試してみましょう。要領は `createMyCustomType` と同じです。

```
type Mutation {
	createMyCustomType(input: CreateMyCustomTypeInput!): MyCustomType
	updateMyCustomType(input: UpdateMyCustomTypeInput!): MyCustomType
	deleteMyCustomType(input: DeleteMyCustomTypeInput!): MyCustomType
}

type Query {
	getMyCustomType(id: ID!): MyCustomType
	listMyCustomTypes(filter: TableMyCustomTypeFilterInput, limit: Int, nextToken: String): MyCustomTypeConnection
}
```

## さいごに

今回紹介しているのはほんの一部だけです。APIを自作したり、データソース(DynamoDBのテーブル)を複数設定したりと、まだまだ様々なことができます。
私自身もまだ試せていないことだらけなので、これからもっと深めていこうと思います。
ではまた！！