2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ローコード開発ツールのRetoolからPostGraphile(GraphQL)を使ってみた

Last updated at Posted at 2021-03-15

記事の内容

  • ローコード開発ツールのRetoolを使用して、PostgreSQLにデータを読み書きするアプリを試作します。
  • 自宅のローカル環境のPostgreSQLを使用しました。
  • 同じくローカルでPostGraphileを起動し、この記事の方法で外部公開し、Retoolアプリからアクセスしました。
  • 本記事ではPostGraphileのユーザー認証は省きました。

HasuraもPostGraphileと類似のプロダクトと認識していますが、本記事では私が利用経験のあるPostGraphileを使用しました。

参考ページ(感謝します)

ローコードアプリ開発プラットフォーム Retool で API 連携アプリを作成

【ローカル環境にて】PostgreSQLにデータを用意し、PostGraphileを立ち上げる

ローカル環境での作業手順はこの記事とほぼ同じですが、若干の違いがありますので再掲します。

ERモデリングツールでの作業

ERモデリングツールはA5:SQL Mk-2を使用しました。
以下のER図を描きました。エンティティ1つだけです。

a10.png

ER図メニューから「DDLを作成する」を選択します。

a11.png

RDBMS種類でPostgreSQLを選択し、DDL生成ボタンを押します。

a12.png

以下の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

a09.png

データベースを作成します。名前を「sample_db」にしましたが、何でも良いです。


CREATE DATABASE sample_db;

a13.png

カレントデータベースを、作成したsample_dbに切り替えます。

\c sample_db

a14.png

先ほどERモデリングツールが生成したDDLをpsqlにコピペして実行します。

a15.png

以下の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;

a16.png

以下のSELECT文を流して、データが作成されたか確認します。


SELECT
    *
FROM
    weather_forecasts;

以下のようにidの降順で表示されましたが、順番に意味はありません。

a17.png

psqlから抜けます。

a18.png

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

起動画面

b00.png

postgraphileコマンドを起動するだけで、PostgreSQLのスキーマを読み取ってGraphQLエンドポイントを自動生成してくれます。
とても楽で、これもローコードと言えるかもしれません。

起動画面によれば、URLは

となっています。

ここでブラウザからGraphiQLにアクセスして、クエリーを発行したりドキュメントを見たりしてみましょう。

クエリー例


query allWeatherForecasts {
  allWeatherForecasts {
    nodes {
      id
      dt
      temperatureC
      summary
    }
  }
}

ブラウザ画面

b03.png

レスポンス


{
  "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にクエリーを発行できました。

b05.png

Retoolでアプリを開発する

Retoolにログイン後、以下の作業を行います。

Resoucesタブでの作業

Resoucesタブに行って、Create newボタンをクリックします。

b01.png

以下のように一覧から接続先が選べますので、GraphQLを選択します。

b02.png

以下のようにNameとBaseURLを設定し、Test ConnectionボタンをクリックしてGraphQLエンドポイントに接続できるか確認します。


Name:sample_db(何でも良いです)
BaseURL:http://your_domain:13001/graphql

b06.png

上図のように「Connection success!」と表示されれば、PostGraphileへの接続は成功ですので、Create resourceボタンをクリックします。
「Resource created」と表示されれば、リソースの作成は成功です。

Appsタブでの作業(その1)データ表示

Appsタブに行って、Create newボタンをクリックします。
出てきたポップアップメニューから、今回は「Create a blank app」を選択しました。

b07.png

query1について、以下の設定を行います。

  • query1の名前を「allWeatherForecasts」に変更
  • Resourceを「sample_db」に変更
  • Queryに以下のクエリーを入力
  • Save & Runをクリック

query allWeatherForecasts {
    allWeatherForecasts {
        nodes {
            id
            dt
            temperatureC
            summary
        }
    }
}

b08.png

table1を選択し、以下を行います。

  • BASIC > Dataに「{{ allWeatherForecasts.data.allWeatherForecasts.nodes }}」と入力
  • Previewボタンをクリック

b09.png

以下のようにアプリが起動し、PostgreSQLのデータが一覧表示されました。

b10.png

Appsタブでの作業(その2)データ新規登録

Editボタンを押してアプリ編集画面に戻ります。
以下のように、Gridの下にTextInputを4つとButtonを1つ、ドラッグ&ドロップして設置します。

b11.png

textinput1の属性を以下のように変更します。


名前:textinput_id
Label:id
Input type:number

b12.png

textinput2の属性を以下のように変更します。


名前:textinput_dt
Label:dt
Input type:date

b13.png

textinput3の属性を以下のように変更します。


名前:textinput_c
Label:temperatureC
Input type:number

b14.png

textinput4の属性を以下のように変更します。


名前:textinput_summary
Label:summary

b15.png

データを新規登録するクエリーを追加します。
以下のようにQueryの「+ New」ボタンをクリックし、Resource queryを選択します。

b16.png

以下の設定を行います。

  • 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ボタンをクリックします。

b17.png

button1を選択し、以下の設定を行います。

  • On clickが「Run a query」になっていなければ「Run a query」にする
  • Select a queryでcreateWeatherForecastを選択する

b18.png

それでは右上のPreviewボタンをクリックして、アプリを動かしてみます。
適当なデータを入力して新規登録してみましょう。

b19.png

Submitボタンをクリックすると、以下のように「Query ran successfully」と表示されました。

b20.png

ブラウザでページを更新(再読み込み)すると、データが1件増えたことが確認できました。
データ一覧の最終ページに移動すると、新規登録したデータが表示されました。

b21.png

以上です。

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?