記事の内容
- ローコード開発ツールのRetoolを使用して、PostgreSQLにデータを読み書きするアプリを試作します。
- 自宅のローカル環境のPostgreSQLを使用しました。
- 同じくローカルでPostGraphileを起動し、この記事の方法で外部公開し、Retoolアプリからアクセスしました。
- 本記事ではPostGraphileのユーザー認証は省きました。
※ HasuraもPostGraphileと類似のプロダクトと認識していますが、本記事では私が利用経験のあるPostGraphileを使用しました。
参考ページ(感謝します)
ローコードアプリ開発プラットフォーム Retool で API 連携アプリを作成
【ローカル環境にて】PostgreSQLにデータを用意し、PostGraphileを立ち上げる
ローカル環境での作業手順はこの記事とほぼ同じですが、若干の違いがありますので再掲します。
ERモデリングツールでの作業
ERモデリングツールはA5:SQL Mk-2を使用しました。
以下のER図を描きました。エンティティ1つだけです。
ER図メニューから「DDLを作成する」を選択します。
RDBMS種類でPostgreSQLを選択し、DDL生成ボタンを押します。
以下のDDLが生成されました。
-- RDBMS Type : PostgreSQL
-- Application : A5:SQL Mk-2
/*
BackupToTempTable, RestoreFromTempTable疑似命令が付加されています。
これにより、drop table, create table 後もデータが残ります。
この機能は一時的に $$TableName のような一時テーブルを作成します。
*/
-- WeatherForecast
--* BackupToTempTable
DROP TABLE if exists weather_forecasts CASCADE;
--* RestoreFromTempTable
CREATE TABLE weather_forecasts (
id integer NOT NULL
, dt date NOT NULL
, temperature_c double precision NOT NULL
, summary character varying NOT NULL
, CONSTRAINT weather_forecasts_PKC PRIMARY KEY (id)
) ;
COMMENT ON TABLE weather_forecasts IS 'WeatherForecast';
COMMENT ON COLUMN weather_forecasts.id IS 'Id';
COMMENT ON COLUMN weather_forecasts.dt IS 'Date';
COMMENT ON COLUMN weather_forecasts.temperature_c IS 'TemperatureC';
COMMENT ON COLUMN weather_forecasts.summary IS 'Summary';
PostgreSQLの作業
本記事ではLinux上のPostgreSQLを使用します。
psqlを起動します。
psql --host=localhost --username=postgres --password
データベースを作成します。名前を「sample_db」にしましたが、何でも良いです。
CREATE DATABASE sample_db;
カレントデータベースを、作成したsample_dbに切り替えます。
\c sample_db
先ほどERモデリングツールが生成したDDLをpsqlにコピペして実行します。
以下のINSERT文を流して、2000年1月1日から150日分のテストデータを作成します。
テーブルにはidの降順でINSERTしてみます。
INSERT INTO weather_forecasts (
id,
dt,
temperature_c,
summary
)
SELECT
id,
('1999-12-31'::DATE + (id::TEXT || ' days')::INTERVAL)::DATE AS dt,
(random() * 75 - 20)::INT AS temperature_c,
CASE (random() * 1000)::INT % 10
WHEN 0 THEN 'Freezing'
WHEN 1 THEN 'Bracing'
WHEN 2 THEN 'Chilly'
WHEN 3 THEN 'Cool'
WHEN 4 THEN 'Mild'
WHEN 5 THEN 'Warm'
WHEN 6 THEN 'Balmy'
WHEN 7 THEN 'Hot'
WHEN 8 THEN 'Sweltering'
WHEN 9 THEN 'Scorching'
END AS summary
FROM
generate_series(1, 150) AS id
ORDER BY id DESC;
以下のSELECT文を流して、データが作成されたか確認します。
SELECT
*
FROM
weather_forecasts;
以下のようにidの降順で表示されましたが、順番に意味はありません。
psqlから抜けます。
PostGraphileの作業
本記事ではPostGraphileをPostgreSQLと同じローカルのLinuxホストにインストールします。
このページを参考にして、PostGraphileをインストール&起動します。
Dockerを使う方法もあります。
インストール
npm install -g postgraphile
起動コマンド例
postgraphile --connection postgres://postgres:secret@localhost/sample_db --port 3001 --schema public --export-schema-graphql ~/schema.graphql
起動画面
postgraphileコマンドを起動するだけで、PostgreSQLのスキーマを読み取ってGraphQLエンドポイントを自動生成してくれます。
とても楽で、これもローコードと言えるかもしれません。
起動画面によれば、URLは
- GraphQLエンドポイント:http://localhost:3001/graphql
- GraphiQL:http://localhost:3001/graphiql
となっています。
ここでブラウザからGraphiQLにアクセスして、クエリーを発行したりドキュメントを見たりしてみましょう。
クエリー例
query allWeatherForecasts {
allWeatherForecasts {
nodes {
id
dt
temperatureC
summary
}
}
}
ブラウザ画面
レスポンス
{
"data": {
"allWeatherForecasts": {
"nodes": [
{
"id": 1,
"dt": "2000-01-01",
"temperatureC": 7,
"summary": "Hot"
},
{
"id": 2,
"dt": "2000-01-02",
"temperatureC": -16,
"summary": "Cool"
},
{
"id": 3,
"dt": "2000-01-03",
"temperatureC": 17,
"summary": "Hot"
},
(中略)
{
"id": 150,
"dt": "2000-05-29",
"temperatureC": 14,
"summary": "Freezing"
}
]
}
}
}
psqlからSELECT文を実行したときはid列の降順で表示されましたが、今回のレスポンスを見ると昇順になっていますね。
この順番は気にしないことにして、先に進みます。
PostGraphileサーバーを外部公開する
この記事のhttpの手順を行って、先程ローカルで起動したPostGraphileサーバーを外部公開しました。ただし、動作確認用Webサーバー(python3 -m http.server 3001)の起動は不要です。
なお、本記事ではhttpsは使用しなかったので、Caddyの手順は行いませんでした。
外部からGraphiQLにアクセスできるか、ブラウザで確認してみます。
VPSのドメインが example.com であれば、アクセス先は http://example.com:13001/graphiql となります。
以下のようにリバースSSHポートフォワーディングを利用して、ブラウザからローカルのPostGraphileにクエリーを発行できました。
Retoolでアプリを開発する
Retoolにログイン後、以下の作業を行います。
Resoucesタブでの作業
Resoucesタブに行って、Create newボタンをクリックします。
以下のように一覧から接続先が選べますので、GraphQLを選択します。
以下のようにNameとBaseURLを設定し、Test ConnectionボタンをクリックしてGraphQLエンドポイントに接続できるか確認します。
Name:sample_db(何でも良いです)
BaseURL:http://your_domain:13001/graphql
上図のように「Connection success!」と表示されれば、PostGraphileへの接続は成功ですので、Create resourceボタンをクリックします。
「Resource created」と表示されれば、リソースの作成は成功です。
Appsタブでの作業(その1)データ表示
Appsタブに行って、Create newボタンをクリックします。
出てきたポップアップメニューから、今回は「Create a blank app」を選択しました。
query1について、以下の設定を行います。
- query1の名前を「allWeatherForecasts」に変更
- Resourceを「sample_db」に変更
- Queryに以下のクエリーを入力
- Save & Runをクリック
query allWeatherForecasts {
allWeatherForecasts {
nodes {
id
dt
temperatureC
summary
}
}
}
table1を選択し、以下を行います。
- BASIC > Dataに「{{ allWeatherForecasts.data.allWeatherForecasts.nodes }}」と入力
- Previewボタンをクリック
以下のようにアプリが起動し、PostgreSQLのデータが一覧表示されました。
Appsタブでの作業(その2)データ新規登録
Editボタンを押してアプリ編集画面に戻ります。
以下のように、Gridの下にTextInputを4つとButtonを1つ、ドラッグ&ドロップして設置します。
textinput1の属性を以下のように変更します。
名前:textinput_id
Label:id
Input type:number
textinput2の属性を以下のように変更します。
名前:textinput_dt
Label:dt
Input type:date
textinput3の属性を以下のように変更します。
名前:textinput_c
Label:temperatureC
Input type:number
textinput4の属性を以下のように変更します。
名前:textinput_summary
Label:summary
データを新規登録するクエリーを追加します。
以下のようにQueryの「+ New」ボタンをクリックし、Resource queryを選択します。
以下の設定を行います。
- query2の名前を「createWeatherForecast」に変更
- Queryに以下のクエリーを入力
mutation createWeatherForecast ($input: CreateWeatherForecastInput!) {
createWeatherForecast (input: $input) {
weatherForecast {
id
dt
temperatureC
summary
}
}
}
- Variables > inputに以下を入力
{
"weatherForecast": {
"id": {{parseInt(textinput_id.value)}},
"dt": {{textinput_dt.value}},
"temperatureC": {{_.toNumber(textinput_c.value)}},
"summary": {{textinput_summary.value}}
}
}
- Saveボタンをクリックします。
button1を選択し、以下の設定を行います。
- On clickが「Run a query」になっていなければ「Run a query」にする
- Select a queryでcreateWeatherForecastを選択する
それでは右上のPreviewボタンをクリックして、アプリを動かしてみます。
適当なデータを入力して新規登録してみましょう。
Submitボタンをクリックすると、以下のように「Query ran successfully」と表示されました。
ブラウザでページを更新(再読み込み)すると、データが1件増えたことが確認できました。
データ一覧の最終ページに移動すると、新規登録したデータが表示されました。
以上です。