Hasura GraphQL Engineと戯れる


Hasuraとは

HasuraはPostgreSQLなどのデータソースから自動的にGraphQLサーバーを作成できるツールです。
対象となるデータソースのアドレスやPasswordを設定して起動すればすぐにGraphQLサーバーとして使えます。
SaaSとして利用することもできますが、Core機能のHasura GraphQL Engineはオープンソースで公開されていますので、Dockerで構築することが可能です。
今回はDockerを使用して自前で構築してみます。

環境構築

こちらからdocker-compose.yamlを入手してyamlがあるディレクトリでコンテナを起動します。

docker-compose up -d

http://localhost:8080 で Hasura Console にアクセスできます。
同じくコンテナでPostgreSQLも起動してきます。

データベースの接続

上部メニューの「DATA」タブからDBへの接続文字列を設定します

テーブルの作成

Hasura ConsoleではDB設定、データ編集も行うことができます。
今回は初期状態のDBなのでテーブルを作成していきますが、既存のDBを接続すると自動的にテーブル情報等を読み取ってくれます。

UUID型のidとText型のnameをもつemployeesテーブルを作成します。

データの挿入と取得

上部メニューの「API」タブからGraphQL を即座に試せるプレイグラウンドツール GraphiQLを使用してAPIを試すことができます。

Hasura GraphQL Engineはテーブルの情報からGraphQLの更新系であるmutationを自動作成してくれるので、insert_employeesをそのまま利用します。

mutation {
  insert_employees(objects: {name: "Yosuke Sakaue"}) {
    affected_rows
  }
}

参照系のqueryは以下のように記述します

query {
  employees {
    id
    name
  }
}

結果

{
  "data": {
    "employees": [
      {
        "id": "24c1de75-9578-497a-9fb2-011dc920572c",
        "name": "Yosuke Sakaue"
      }
    ]
  }
}

テーブルのリレーション

idとnameをもつdepartmentsテーブルを新たに作成します。

employeesテーブルにUUID型のdepartments_idカラムを追加します。

そしてForeign Keysを設定します。

テーブルの「Relationships」タブからリレーションを設定します。
foreign keys を参考にしてリレーションのサジェストをしてくれているのでそのまま「Add」します。
リレーションとは、GraphQL のリソースを結合するためのものです。

データの挿入と取得②

「API」タブでデータの挿入をします。

departmentsテーブルに組織情報を挿入

mutation {
  insert_departments(objects: {name: "software development"}) {
    affected_rows
    returning {
      id
    }
  }
}

結果

{
  "data": {
    "insert_departments": {
      "affected_rows": 1,
      "returning": [
        {
          "id": "20b0042c-bc31-4657-8178-d4e7e097b668"
        }
      ]
    }
  }
}

返却されたidをemployeeの社員情報にupdateします。

mutation {
  update_employees(where:
    {id:{_eq: "24c1de75-9578-497a-9fb2-011dc920572c"}},
    _set: {departments_id: "20b0042c-bc31-4657-8178-d4e7e097b668"}){
    affected_rows
  }
}

GraphQLの強みである一括取得を試してみます

query MyQuery {
  employees {
    id
    name
    department {
      id
      name
    }
  }
}

結果
一度のリクエストで社員の情報と紐づく組織の情報も一括で取得することができました。

{
  "data": {
    "employees": [
      {
        "id": "24c1de75-9578-497a-9fb2-011dc920572c",
        "name": "Yosuke Sakaue",
        "department": {
          "id": "20b0042c-bc31-4657-8178-d4e7e097b668",
          "name": "software development"
        }
      }
    ]
  }
}

まとめ

今回は新規でテーブルを作成していきましたが、既存のRDBを接続するだけでAPIサーバーを作成できるのは非常に便利で可能性を感じました。
単純なCRUDサービスを構築するだけならこれで十分ですし、Hasuraには他にもActions、Remote Schemas、Event Triggers、認証・認可、ページネーション自動作成など様々な機能があるのでそちらもまた記事にしたいと思います。