LoginSignup
4
2

More than 3 years have passed since last update.

GraphQL、AppSyncを使ってDynamoDBにデータを挿入してみた

Last updated at Posted at 2019-11-03

今回はGraphQLAppSyncを扱って、DynamoDBにデータを挿入する方法を記事にしてみました。

Schemaを定義する

以下のようにAppSyncSchemaから定義することも可能なのですが、
スクリーンショット 2019-11-02 18.44.28.png

私はAmplify CLIで作成されるテンプレートであるschema.graphqlのファイルを直接編集することでデータを定義していきたいと思います。尚、schema.graphqlAmplify用のプロジェクトを準備するamplify init コマンドを叩いた際に自動生成されます。この記事以降AmplifyのCLIコマンドを使いアプリを実装していくため、Schemaはプロジェクトファイルの方で定義していきます。

データの設計

ホテルの管理画面アプリを例にデータの設計を考えてみます。必要なデータは

カラム名 物理名
宿泊部屋のタイプ(シングル、ダブルなど) type
部屋の状況(予約されているか、空室かなど) status
部屋番号 number
部屋の清掃状況 houseKeeping
宿泊者情報 guestInfo
宿泊者代表名 name
いつ来たのか startedAt
いつ帰るのか leavesAt

ざっとこんな感じですかね。

実際にSchemaに定義してみる

schema.graphqlには以下のように定義しました

schema.graphql
type UserType @model {
  id: ID!
  type: String!
  status: String!
  number: String!
  houseKeeping: [String]
  guestInfo: GuestInfo
}
type GuestInfo {
  name: String
  startedAt: String
  leavesAt: String
}

guestInfo に中身をオブジェクトにし、namestartedAtleavesAtの3つを持つように設計しました。
続いてUserTypeテーブル(テーブル名を自身で定義したもの)の中身に説明が必要なワード、記号について解説していきます。

@modelについて

以下公式サイトから引用

GraphQL Transform 使用して、DynamoDB によってサポートされる API の最上位オブジェクトタイプを定義するディレクティブです。必要なすべての CRUDL (作成、読み取り、更新、削除、および一覧表示) クエリと変化、およびそのような変化の通知を受けるサブスクリプションを生成する

今回の例でいうと、UserTypeテーブルが最上位のオブジェクトタイプになり、GuestInfoが第2次のオブジェクトタイプになるため、UserTypeの横に@modelをつけます。@modelをつけることにより、最上位のテーブル同士でデータのやり取りができるようになる@connectionなど新たなディレクティブが使用できるようになります。

!について

!が意味することは「必ずデータを挿入しなければいけない」です。NOT NULL制約(undefined値、null値は受けつけない)ですね。今回の例で言えばguestInfoのデータは挿入しなくてもいいけど、typeは入れなきゃエラーで怒られるよって定義することになります。必須フィールドには!をつけましょう!

DynamoDBとの連携(create)

Schemaを定義した後、amplify pushコマンドを叩き、App SyncSchema情報を登録しましょう。
SchemaAppsyncに反映されたのを確認したら、いよいよクエリ言語のGraphQLでデータを挿入してみます。

GraphQL
mutation user {
  createUserType(input:{
      status:"occupied"
      number:"101"
      type:"family"
      houseKeeping:["clean"]
      guestInfo: {
        name:"Ichiro Suzuki"
        startedAt:"2017-09-15"
        leavesAt:"2017-09-18"
      }

  }) {
    id
    number
    type
    houseKeeping
    guestInfo {
    name
    startedAt
    leavesAt
  }
  }
}
結果
{
  "data": {
    "createUserType": {
      "id": "35dba6de-013a-45b9-bc21-165bdaded3ca",
      "number": "101",
      "type": "single",
      "houseKeeping": [
        "clean"
      ],
      "guestInfo": {
        "name": "Ichiro Suzuki",
        "startedAt": "2017-09-15",
        "leavesAt": "2017-09-18"
      }
    }
  }

スクリーンショット 2019-11-01 22.22.21.png

手順と一緒に解説していきます。

Type型の宣言

スクリーンショット 2019-11-01 22.15.22.png

GraphQLはリクエストのみのquery、データを変更するmutation、サーバーサイドからのイベントを通知できるsubscriptionによる3つのtype型があります。今はデータを挿入したいのでmutationを宣言します

GraphQL
mutation user {

ちなみにuserの変数名は自由に変更できます

②クエリ実行

mutationつまりデータの変更にはデータを新しく作るcreate、削除するdelete、更新するupdateの3つがあります。
ここでイチロー選手がホテルに宿泊する新しいデータを作ってみましょう。そのために、create+UserType(テーブル名)を書いてあげます

GraphQL
createUserType(input:{
      status:"occupied"
      number:"101"
      type:"family"
      houseKeeping:["clean"]
      guestInfo: {
        name:"Ichiro Suzuki"
        startedAt:"2017-09-15"
        leavesAt:"2017-09-18"
      }
  ・・・

③返して欲しいデータを書く

GraphQL
 {
    id
    number
    type
    houseKeeping
    guestInfo {
    name
    startedAt
    leavesAt
  }
  }
}

このようにクエリを実行した後、返して欲しいデータを書きます。極端な話、idだけでも大丈夫です。返して欲しくないデータがあれば、通信量などを考慮し、書かない選択も可能です

以上の手順を行うと、このようにDynamoDBにデータが挿入されます。

スクリーンショット 2019-11-01 22.54.24.png
スクリーンショット 2019-11-01 22.54.34.png

DynamoDBとの連携(list)

次にテーブルのデータの一覧を取得したい場合のquery型からlistのクエリも実行してみたいと思います

GrapQL
query list {
  listUserTypes {
    items {
      number
    }
  }
}
結果
{
  "data": {
    "listUserTypes": {
      "items": [
        {
          "number": "103"
        },
        {
          "number": "202"
        },
        {
          "number": "203"
        },
        {
          "number": "403"
        },
        {
          "number": "101"
        },
        {
          "number": "402"
        },
        {
          "number": "201"
        },
        {
          "number": "401"
        },
        {
          "number": "302"
        },
        {
          "number": "303"
        },
        {
          "number": "102"
        },
        {
          "number": "301"
        }
      ]
    }
  }
}

numberデータが全て取得できました!

因みにnumberは「数値型」の意味なので、命名としては良くないと言うご指摘を受けました。
roomNumberなどにするべきでしたね、、、、今後変数名には気をつけます!

次回はAmplifyの認証機能について記事を書いていこうと思います!

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2