【HASURA】チュートリアルをやってみた

# はじめに

> Hasuraは、承認とアクセス制御があるCRUD + リアルタイムGraphQL APIを提供します。

https://hasura.io/learn/ja/graphql/hasura/introduction/

> このコースでは、HasuraによるGraphQLバックエンドの設定について簡潔に紹介します。
30分で、クエリ、ミューテーション、サブスクリプションを備えた強力でスケーラブルなリアルタイムGraphQLバックエンドを設定します。また、Hasuraが、ユーザーが書いたカスタムGraphQL APIsとして、また非同期で実行されてデータベースイベントによってトリガーされるイベントトリガーとして、カスタムビジネスロジック（任意のプログラミング言語）の統合にどのように役立つかを学びます。

こちらのチュートリアルをやってみます
30分で終わると書いてありますが、さてどうでしょうか？

# 内容
> Hasuraを使ってPostgresデータベースを活用したリアルタイムGraphQL APIを生成します。
### Hasuraをデプロイ
##### アカウントを作成しプロジェクトを作成
<img width="300" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/bfc3e947-7079-25c5-446d-0232c88912c1.png">

### データモデリング

https://hasura.io/learn/ja/graphql/hasura/data-modeling/

##### データベース接続
- 既存のデータベースへの接続
- 新しくHerokuデータベースを作成する（無料）

ということなのでHerokuを使っていきます
<img width="300" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/4cd993f1-815e-3cf3-8f7e-26500ad32903.png"><img width="300" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/8ed551cd-082a-f02e-ea10-25256b6a55a7.png">

##### テーブルを作成する
![スクリーンショット 2022-06-22 1.12.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/8fc7d0fa-3055-5bea-43b1-ae3e9c0a8f9f.png)

##### GraphQL APIを使ってみる
![スクリーンショット 2022-06-22 1.17.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/7da6795d-494e-b96d-414d-172df8a74dd2.png)
![スクリーンショット 2022-06-22 1.18.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/1aa64cf6-7eae-0511-eaef-bdccfc07570f.png)

### リレーションシップ

https://hasura.io/learn/ja/graphql/hasura/relationships/

##### 外部キーを作成
![スクリーンショット 2022-06-22 1.45.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/71b1d8c9-45ec-dd79-08ea-4ccdc6466af7.png)

##### リレーションシップを作成
外部キー制約が作成されたため、Hasuraコンソールがそれに基づき自動的にリレーションシップを提案してくれる
![スクリーンショット 2022-06-22 1.47.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/b477d2e5-8056-dd9c-a81e-9ee48a4b17eb.png)

##### リレーションシップクエリを試す
![スクリーンショット 2022-06-22 1.51.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/4b2b853b-2544-0155-7acd-f950f11edee6.png)

### データ変換

https://hasura.io/learn/ja/graphql/hasura/data-transformations/

##### `PostgreSQL View`の作成

> ビューを作成するとクエリに名前が付けられ、通常のテーブルから行うのと同じように、このビューからSELECTを実行できるようになります。

![スクリーンショット 2022-06-22 2.04.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/648a83a5-3517-c477-d3c2-1baf444cc193.png)

##### オンラインユーザーへのサブスクリプション

過去30秒にログインしオンラインになっているユーザーをアプリが検索するビューを追加して、Hasuraでビューを追跡して、クエリできるようにする
![スクリーンショット 2022-06-22 2.05.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/e2565710-2f5c-7c1d-9f74-71c48e05bba0.png)
![スクリーンショット 2022-06-22 2.06.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/52043357-4ae3-0428-95d3-425275e0986c.png)

##### ユーザーへのリレーションシップを作成
> ビューが作成されたら、ビューの id 列に基づいて、ユーザー情報を取得できるようにする方法が必要です。ビューの id column を使って、ビュー online_users からテーブル users への手動のリレーションシップを作成しましょう。
リレーションシップのタイプを Object Relationship にすることにより、手動で新しいリレーションシップを追加します。リレーションシップ名を user として入力します。現在の列の設定を id として選択すると、リモートテーブルは users になり、リモート列は再度 id になります。

![スクリーンショット 2022-06-22 2.13.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/452a5efd-b2ec-69e4-a8ab-491e97b3c750.png)

### 承認

https://hasura.io/learn/ja/graphql/hasura/authorization/

##### テーブル権限を設定する
テーブルの各処理（insert, select, update, delete）に対して権限を設定していく
例えば、user_Idの値がセッションのUser_Idと一致している場合のみ処理を許可など

> セッション変数は、各要求の認証サービスから返されるキーと値のペアです。ユーザーが要求すると、セッショントークンは USER-ID にマッピングされます。この USER-ID は許可で使用され、user_id 列にセッション変数 USER-ID の値に等しい値がある場合にのみ、テーブルへの挿入が許可されることを示すことができます。

![スクリーンショット 2022-06-22 9.20.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/e5fec7cb-b4c0-30d5-e363-f81334beef65.png)
![スクリーンショット 2022-06-22 9.30.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/9d2a4d9c-58e3-0e8a-26f1-fdf264c9c23f.png)
![スクリーンショット 2022-06-22 9.43.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/0a923fc2-b182-b439-72cb-d2bd0da7e7fe.png)

##### 設定した権限の有効性を試す

Request headerに`role`と`user-id`を指定することで
権限次第で結果がフィルタリングされる
![スクリーンショット 2022-06-23 9.00.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/839cbabf-35c6-6ffc-cc37-62d5da4cfbf5.png)

### 認証

ここでは認証プラットフォームのAuth0を使います

https://auth0.com/jp

ダッシュボードからAppとAPIを作成していきます

<img width="300" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/8b0933a9-e7e2-4ccd-2688-232cd3a62660.png">
<img width="300" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/1fc1dd3b-898e-f542-1c65-a0abeabfcef5.png">

JWTルールを設定（JSON Web Token）
![スクリーンショット 2022-06-23 12.53.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/32674be7-ccf0-6e82-9016-64e9af21c1a2.png)


##### HasuraをAuth0に接続する

> HasuraがAuth0公開鍵を使用するように設定する必要があります。JWTの設定を生成する簡単な方法は、このリンクを使用することです。
HASURA_GRAPHQL_JWT_SECRET という新しい Config Varを追加して、生成されたJWT設定を値ボックスにコピーアンドペーストします。
これでHasuraインスタンスがAuth0を使って保護されます。

https://hasura.io/jwt-config/

![スクリーンショット 2022-06-23 16.01.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/74bf7618-5e11-efaf-4de1-9ea976d14569.png)

##### Rulesでユーザーを同期する

> Auth0におけるルールを設定して、Auth0のユーザーがデータベース内のユーザーと同期できるようにする必要があります。
このルールは、サインアップまたはログインが成功するたびにトリガーされます。そして、Hasura GraphQLミューテーションを使用して、ユーザーデータをデータベースに挿入または、更新します。

![スクリーンショット 2022-06-23 16.14.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/497b1e93-0cff-d365-5ed8-7a4bb293c257.png)

##### Auth0トークンで試す

認証が正常に動くか確認できる
正常にログインの動きが確認できて、HasuraのDBのuserテーブルに新規ユーザが登録されていれば完了

![スクリーンショット 2022-06-23 16.16.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/07f1dfb3-1e07-587f-77c4-fc37ea0632b0.png)

##### カスタムビジネスロジック

https://hasura.io/learn/ja/graphql/hasura/custom-business-logic/

アプリにカスタム/ビジネスロジックを追加したい場合
> 例えば、構築中のtodoアプリで、公開フィードにtodoを挿入する前に、テキストに不適切な表現が含まれていないかを検証したい場合などです。

に使えてとても便利そうですが、必須ではなさそうなので、今回はここまで

# おわりに

30分では終わりませんでした。2時間ぐらいかかりました😅

最終的にiOSアプリの認証とデータ管理までやりたいので、引き続きやっていきます〜

(記事ではなく、ただの作業メモとなりました...)

# 参考

https://zenn.dev/eringiv3/articles/c44d5400e5603e

https://qiita.com/maaz118/items/9e198ea91ad8fc624491

https://tech.buysell-technologies.com/entry/adventcalendar2021-12-09