サーバーレスのビジネスロジックを任意のクラウドで楽に実行できるリアルタイムGraphQL API
Takeshi Amano
Posted on April 8, 2019
この記事は以下のVladimir Novicの記事を翻訳したものです。
Effortless Real-time GraphQL API with serverless business logic running in any cloud
Vladimir Novick ・ Feb 5 '19
この記事では、サーバーレスのビジネスロジックを使用して、楽にリアルタイムGraphQL APIを作成し、それをあらゆるクラウドにデプロイする方法を紹介します。釣り記事のように聞こえますか?楽にってどういうこと?全く何もしなくてもいいという訳ではありません。あなたがGraphQLに精通しているか、またはそれについて聞いたことがある、そしてどうやってGraphQLサーバを書き始めるのか疑問に思っているならば、あなたは我々があなた自身のGraphQLサーバをつくると思うかもしれません。またクラウドの導入、サーバーレス機能を扱うことになるでしょう。複雑な事に聞こえますよね。
えーと、ここでのキーワードは「楽に」です。既存のPostgresまたはその拡張機能の上に、自分の選んだ任意のクラウドで独自のGraphQL APIをセットアップして実行するのは非常に簡単です。この記事ではサーバーをセットアップしたりクラウドの展開について話したりすることはありません。ほんの少しだけはあるかな。この記事では、Hasura.ioオープンソースエンジンのほとんどの機能セットと、独自のサーバーを作成せずにリアルタイムGraphQL APIを実現する方法について説明します。既存のサーバー、Postgres以外のデータベース、またはサーバーレスの機能であっても、その機能を使用して詳細な概要とユースケースを説明します。
目次
GraphQLの紹介
- Hasura GraphQLエンジンの説明、オープンソースの理由
- Herokuで始めましょう
- 他のクラウドでの使い方?
- 既存のPostgresの上で走らせる
- Postgresエクステンションについて(PostGIS、TimescaleDB)
- Postgresを使わない場合
- Hasuraエンジンコンソールの概要
- データモデリング、関係、およびアクセス制御
- 認証
- リモートスキーマとも呼ばれるカスタム外部GraphQLサーバー
- イベントトリガーによる非同期のサーバーレスビジネスロジック
GraphQL
GraphQLは流行語であるだけでなく、REST APIを徐々に置き換えているサーバーと通信するために広く採用されている方法です。一言で言えば、GraphQLはAPIとデータを定義する特定の型システムのための問い合わせ言語です。データの形状を定義し、サーバーでこのデータを取得する方法を定義した後は、クライアントで特定のクエリ形式を使用してデータの変更を照会(query)、変更(mutation)、または購読(subscribe)することさえできます。あなたが受け取るデータはあなたが要求したのと全く同じ形になるでしょう。このブログ記事では、GraphQLとは何なのかについては詳しく説明しませんが、GraphQLを初めて使用するのであれば、無料の4日間Bootcampをやっています。
React、Angular、またはVueで既存のGraphQL APIを使用する方法を説明し、NodeJSで独自のGraphQL APIを作成する方法も学習します。
この記事のタイトルから想像できるように、ここでは楽なリアルタイムGraphQL APIについて話します。魔法のようですね。しかし確かにhasura.ioオープンソースのGraphQLエンジンでそう感じています!ここから飛び込んでみましょう!
Hasura GrahphQLエンジンとは何ですか?オープンソースの理由
Hasura engineはdockerコンテナ内で動作するエンジンを提供し、新規または既存のPostgresデータベースの上にレイヤーとして存在します。
GraphQL APIを最初から容易に作成することができるだけでなく既存のPostgresデータベースの上でエンジンを走らせることができます。
Dockerコンテナーで実行されているので、基本的に、Heroku、Digital Ocean、AWS、Azure、Zeit、GCP、さらにはローカル環境でも、dockerが実行可能な場所ならどこでも実行できます。
Hasuraエンジンには使いやすいUIが付属しており、GraphiQLツールを使用してquery、mutation、subscriptionをテストすることができます。
それではなぜそれがオープンソースなのでしょうか?それが、hasura.ioの共同創設者であるTanmai Gopalに尋ねた質問です。
それはあなたのスタックの一部だからです。そして今の時代には、オープンソースコンポーネントの透明性と柔軟性が必要です。オープンソースにより、コミュニティへの移行、セキュリティの強化、拡張の柔軟性、およびコミュニティへの参加を促進します。コミュニティによって、オープンソース製品をさまざまな環境で実行できるようになります。 Hasuraは、私たちのコミュニティの助けを借りて、自分の好きな環境でそれを実行し、プロジェクトに情報を提供するマルチクラウドおよびマルチプラットフォームです。
Herokuで始めましょう
hasura.ioにアクセスしたときに最初に出てくるのは、無料のオプションとしてのHerokuへのデプロイ方法です。
これは非常に迅速で非常に堅実なインストール法ですが、プロダクショングレードのアプリケーションの場合は、別のクラウドを使用することを検討する必要があります。ご覧のとおり、さまざまなクラウドオプションから選択できますが、シンプルにはじめるためにHerokuの無料利用枠の基本設定から始めましょう。
この「Deploy to Heroku」ボタンをクリックすると、HasuraエンジンがHeroku PostgresアドオンとともにHerokuにデプロイされます。
ここでは何が起こっているの?
Herokuにはデプロイ可能なテンプレートの概念があります。したがって、Herokuへのデプロイを実行しているときに起こっているのは、このリンクをクリックしているということです。
https://heroku.com/deploy?template=https://github.com/hasura/graphql-engine-heroku
実際ここで展開しているテンプレートは次のとおりです。
https://github.com/hasura/graphql-engine-heroku
さらに詳しい説明
このテンプレートのapp.jsonファイル(Herokuの設定が定義されているファイル)を確認しましょう。
このjsonファイルはHerokuにPostgresアドオンを使用してWebレイヤーを無料プランでデプロイするように伝えます。
app.jsonと一緒にheroku.ymlもあります。
Dockerが全部やってくれる!
ご覧のとおり、実行するDockerfileがあることを指定しています。そのため、Herokuへのデプロイは基本的に、dockerコンテナをHerokuにデプロイする際の構文上の問題になります。 Digital Oceanの場合、ワンクリックデプロイは少し異なりますが、同じ考え方に沿っています。
Digital OceanイメージはUbuntu + docker + Postgresがすでに設定されているだけです。
AWSとAzureの設定はもう少し複雑ですが、考え方は同じです。Dockerコンテナでエンジンを実行し、それをPostgres dbに接続するというものです。
他のクラウドは?
あなたがおそらく考え出したように、hasura.ioエンジンを動かすことはあなたがDockerとPostgresを動かすことができるどこでも可能です。 AWS、Azure、Zeit、GCPなんでもありです。
たとえば、Hasuraをローカルの環境に設定しましょう。
前提条件
エンジンをローカルにインストールする前に、DockerとDocker Composeが必要です。ここからインストールできます。
マニフェストの取得
それでは、docker-composeファイルを次のリポジトリから取得しましょう。
https://github.com/hasura/graphql-engine/tree/master/install-manifests
このリポジトリには、Hasuraをどこにでもデプロイするために必要なさまざまなインストールマニフェストが含まれています。
それを取得するには、新しいディレクトリを作成して実行します。
wget https://raw.githubusercontent.com/hasura/graphql-engine/master/install-manifests/docker-compose/docker-compose.yaml
Docker containerの実行
docker-compose up -d
ここでコンテナが実行されているかどうかを確認します。
docker ps
この様な出力が確認できるはずです
ご覧のとおり、エンジンインスタンスはPostgres dbと共に実行されています。
これでhttp://localhost:8080/からコンソールに行けます。
既存のPostgresの上で走らせる
Hasuraエンジンを既存のPostgresデータベースの上で実行することも可能です。そのために、以前のようにdocker-composeを取得する代わりに、install-manifestsリポジトリからdocker-run.shスクリプトを取得し、HASURA_GRAPHQL_DATABASE_URL
変数を編集します。ここから詳細を読むことができます。
Postgresエクステンションについて
完全に動作します。このようにHasuraでPostGIS(Postgres用の空間データベース拡張)を使用することについての素晴らしいブログ投稿がいくつかあります。
または、このブログ記事で説明されているように、TimeScaleDB(完全なSQLサポートを備えたオープンソースの時系列データベース)でHasuraを使用できます。
Postgresを使わない場合
Firebaseを使っていますか? firebase2graphqlというfirebaseからの移行ツールがあります。 mongoや他のNoSQLデータベースを使っていますか?JSONダンプをエクスポートして、Hasuraエンジンを通してPostgresデータベースにデータをインポートするためのjson2graphqlツールを使うことができます。 MySQLを使用している?問題ない。 https://www.symmetricds.org/を使用してMySQLからPostgresに移行することも、PostgresをMySQL内のデータのプロキシにするためにPostgres FDWを使用することもできます。
Hasuraエンジンコンソールの概要h
これでPostgresデータベースだけでなく、PostGISなどのPostgres拡張機能やTimeScaleDBなどのオープンソースDB上でも、エンジンをローカルまたは任意のクラウドで実行できることがわかりました。しかし、エンジンの機能についてはまだ話していません。それでは、エンジンをローカルで実行したときに見たコンソールに戻りましょう。
コンソールには4つのメインタブがあります
GraphiQL
Endpointとヘッダー
このページの一番上には、クライアントからGraphQL APIにアクセスしたい場合に付ける必要のあるRequest HeaderとAPIのEndpointがあります。
新しく作成した例でわかるように、Content-Typeヘッダーしかありません。これは、誰もが私たちのAPIにアクセスできるため、実際には安全ではありません。あなたはそれについての通知をあなたのエンドポイントを保護する方法を説明するドキュメントにあなたを導くでしょう右上のコーナーにあなたのエンドポイントに導くでしょう。
安全なアクセスを持つAPIの別の例を示します。
新しく作成した例でわかるように、Content-Typeヘッダーしかありませんhttps://res.cloudinary.com/practicaldev/image/fetch/s--UvkbDOJt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2A9bQps8vAjxbfixptH-jzcA.png。これは、誰もが私たちのAPIにアクセスできるため、実際には安全ではありません。画面の右上にある「Secure your end point」から詳細を確認することがでいます。
こちらがより安全なアクセスのAPIの別の例です。
ここでは、エンドポイントを保護するX-Hasura-Access-Keyヘッダーがあることがわかります。コンソールへのアクセスも保護されます。
GraphiQLのIDEエクステンション
GraphiQLタブには GraphiQL IDEが組み込まれています。これによりブラウザからGraphQL APIをテストするためのquery, mutation, subscriptionを実行することができます。 GraphQLスキーマのドキュメントを調べて、データの形状、および実行できるquery, mutation, subscriptionを確認することもできます。 HasuraエンジンはGraphiQLの上に追加の機能を追加します。
- Prettify - 左側のパネルでGraphQLの構文を最適化します
- History - 最後に実行されたquery, mutationを表示します
- Analyze - これは本当に素晴らしいツールです。 Hasuraエンジンはリゾルバーを実行してデータを取得するのではなく、実際にはGraphQLクエリをSQLクエリにコンパイルします。 [Analyze]ボタンをクリックすると、コンパイル方法がわかります。
以下のqueryを見てみましょう
{
posts {
author {
user {
name
}
}
}
}
Analyzeボタンをクリックすると以下の画面が表示されます
ここでは、データベースに対してクエリがどのように実行されるのかを分析でき、あなたやDBAがデータベースの関係をより効率的にする検討することができるようになります。
Data
このタブはあなたのPostgresデータベースの管理者のようなものです。ここであなたはあなたのスキーマ構造、テーブルリレーション、ロールとパーミッションの設定を定義でき、さらにカスタムSQLを実行することもできます。次のセクションでデータモデリングについて紹介します。
リモートスキーマ
[Remote Schema]タブは、カスタムビジネスロジック用にカスタムGraphQLサーバーのURLを指定できるタブです。
Hasuraエンジンはあなたのhasura GraphQL APIとあなたのカスタムGraphQLサーバーの間のスキーマステッチをするでしょう。たとえば、データベースに何かを追加する前にカスタムビジネスロジックを実行することを考えている場合は、独自のGraphQLサーバーに変換を記述し、サーバーURLを含むhasuraエンジンにセキュリティ用のヘッダーを追加します。
イベント
Hasuraエンジンは強力なイベントシステムをもっています。データベースに何かが挿入、更新、削除されたときはいつでも、イベントを発生させることができます。イベントをサーバーレス機能に関連付けることをお勧めします。次のセクションで詳細を説明します。
テーブルの作成や更新
[Data]タブにアクセスすると、テーブルを作成するオプションがあります。テーブルを作成するときには、その列と型を指定する必要があります。
Hasuraはあなたにヘルパー機能も提供します。私たちの場合、post id主キーのためのユニークな識別子の自動生成のためのgen_random_uuid()
です。ここでは、主キー列または複数の列を選択する必要があります。
他のデータベース管理の様に、外部キーマッピングを異なるテーブルに設定することができます。次の例では、posts
テーブルのauthorId
をauthors
テーブルのidカラムにマッピングしています。
この例からもわかるように、すでにテーブルがある場合はいつでも、テーブルの変更、行の参照、行の挿入、または関係の追加を行うことができます。
クエリの自動生成
Hasuraいいところは、テーブルを追加するたびに、テーブル上の次のqueryとsubscriptionにアクセスできることです。
ご覧のとおり、それらはかなり強力なものです。データをqueryやsubscribeするだけでなく、フィルタ処理もできます。そしてもちろんquery, mutation, subscriptioが実行できます。
関係ビルダー
[Relationship]タブにアクセスすることで、テーブル間に2種類の関係を構築できます。
- Object Relationship
- Array Relationship
たとえば、ユースケースのposts
テーブルのauthorId
列がauthors
テーブルのid
を指す外部キーが設定されていると、posts
に対してクエリを実行できますが、authors
テーブルからGraphQLで入れ子のデータを取得することはできません。そのためには、Object Relationshipを設定する必要があります。
Object Relationshipを作ることをUIのさまざまな部分で提案されます。そのため、提案されたオブジェクトの関係で[Add]をクリックするか、手動で関係を作成できます。
そうするたびに、あなたはこのようなクエリを実行することができるでしょう:
{
posts {
id
author {
bio
}
}
}
パーミッション
Hasuraエンジンでは、ロールとパーミッションを定義し、非常に細かくパーミッションを設定することができます。たとえば、特定のルールが満たされている場合にのみ、特定の列へのアクセスを許可できます。また、カスタム認証Webフックから変数を渡し、それに基づいてカスタムアクセスを定義することもできます。コンソールでは次のようになります。
この例では、提供されているかどうかX-HASURA-USER-ID
をチェックします。
認証
Hasuraエンジンはさまざまな種類の認証をサポートしています。 JWTトークン、カスタムトークン、またはHasura-access-keyを使用できます。内部で起こることは次の通りです:認証層は秘密鍵トークン/ JWT設定またはwebhook設定をチェックします。
Herokuの例を見てみましょう。
これで、Herokuダッシュボードに設定された環境変数がわかります。
-
HASURA_GRAPHQL_ACCESS_KEY
- 秘密鍵トークン -
HASURA_GRAPHQL_AUTH_WEBHOOK
- カスタム認証プロバイダのURL -
HASURA_GRAPHQL_JWT_SECRET
- JWTの設定
たとえばHASURA_GRAPHQL_ACCESS_KEY
を使用する場合は、APIまたはコンソールにアクセスできるようにX-Hasura-Access-Key
を提供する必要があります。
あなたはここで異なる認証オプションについてもっと読むことができます。
リモートスキーマとも呼ばれるカスタム外部GraphQLサーバー
それでは、リモートスキーマを何に使用しますか?次の例を考えましょう。いくつかのカスタムサーバー検証に基づいてデータベースに行を挿入したいとしますが、それでもデータベースの変更をサブスクライブしたいとします。その場合は、リモートスキーマを自分で作成するか、hasuraボイラープレートのいずれかを使用して作成し、カスタムサーバーのGraphqlエンドポイントURLを指定して接続します。
あなたのサーバー上で、hasuraエンジンが接続されている同じデータベースに行を挿入する前に、リゾルバーがカスタムロジックを実行するように定義されたmutationがあるとしましょう。では、データが挿入されるとどうなるでしょう? hasuraエンジンからのGraphQL subscriptionは期待通りに実行されます。
イベントトリガーによる非同期のサーバーレスビジネスロジック
上記のように、hasuraはイベントの強力な概念を持っています。イベントは、テーブル操作だけでなく列の変更時にも発生する可能性があります。イベントがトリガーされるたびに、イベントデータはwebhook URLに渡されます。これらのWebフックはサーバーレス機能であることをお勧めします。サーバーレス機能を作成するためにこれらのボイラープレートをチェックできます。
まとめ
この概要からわかるように、hasura.ioプラットフォームは非常に柔軟で、ほとんどどこでも実行でき、GraphQL APIをあらゆるレベルの複雑さで簡単に作成するのに役立つ多くの機能を備えています。また、Hasuraはオープンソースであり、HaskellとJavaScriptで書かれているので、すべての貢献は大歓迎です。また、DiscordでHasuraに参加するか、Twitterでフォローすることもできます。
Posted on April 8, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.