国産ローコードツールQuerierで、PostgreSQLへのCRUDアプリを作る（REST API編）

# はじめに

YesCoderの私ですが、先日リリースされた国産ローコード開発ツール「[Querier](https://www.querier.io/)」を試したら良かったので、記事にしますよ。
今回はREST API編、次回はGraphQL編の予定です。
Web上でドラッグ＆ドロップで簡単にUIを構築できる開発ツールです。

Querierの気に入った点はいろいろありますが、まず一つ挙げるなら、SQLデータベースやFiresbase等の外部データと簡単に連携できるところですね。
一般にNoCode／LowCodeでの開発は、今はNoCodeデータベースを使うことが多いと思います。
でも本格的なシステムを作るなら、大規模データで実績のあるデータベースを採用したいです。
NoCodeデータベースとNoCodeアプリの組み合わせは、大規模の実績は私の耳に入ってきませんが、Querierのように外部データベースと連携できる開発ツールなら、LowCodeで本格的なシステム開発もいけると私は見ています。

そして本格的なシステム開発もいけるなら、いよいよ「YesCodeのかなりの仕事がNoCode／LowCodeで置き換わる」話が現実味を帯びてきます。
Querierからは、そんな未来を感じました。

Querierは管理画面の開発に特化した、バックエンドエンジニア向けのローコード開発ツールですが、今後はプロダクト向けでも、外部データベースと簡単に連携できる開発ツールが出てくるかもしれませんね。
私もYesCodeの仕事が減りそうで、うかうかしていられません。

それではQuerierのフリープランで、CRUDアプリを試作してみます。

# 記事の内容

- ローコード開発ツールのQuerierを使用して、PostgreSQLにデータを読み書きするWebアプリを試作します。
- 自宅のローカル環境のPostgreSQLを使用しました。
- 同じくローカルで[PostgREST](https://postgrest.org/en/latest/index.html)を起動し、[この記事](https://qiita.com/kanedaq/items/4c3d37d278e674df6e14)の方法で外部公開し、Querierアプリからアクセスしました。PostgRESTは、PostgreSQLを操作するRESTful APIを提供する、オープンソースのWeb APIサーバーです。
- 本記事ではバリデーションやPostgRESTのユーザー認証は省きました。

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

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

ERモデリングツールは[A5:SQL Mk-2](https://a5m2.mmatsubara.com/)を使用しました。
以下のER図を描きました。エンティティ1つだけです。

![a10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/2bc3e939-c1e7-662b-6e37-adf4d3762f6b.png)

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

![a11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/580e4a58-3c1e-afa8-7c47-79e72c0f8d5c.png)

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

![a12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/2756a184-d9f9-db3c-3fcc-7085699f6f29.png)

以下のDDLが生成されました。

```sql

-- 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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/7f3aa0ff-dbe6-20cd-abdc-6b83838dbca5.png)

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

```sql

CREATE DATABASE sample_db;
```

![a13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/5c542d5f-80a4-12d1-3129-503b02fde128.png)

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

```
\c sample_db
```

![a14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/199852b4-9249-3385-bc68-2e441bf918cf.png)

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

![a15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/c5a76dc0-911e-ddd3-f71d-c9f145a96b91.png)

以下のINSERT文を流して、2000年1月1日から150日分のテストデータを作成します。
テーブルにはidの降順でINSERTしてみます。

```sql

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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/86580e77-2bc5-cbe5-75ae-59a8c8fb916e.png)

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

```sql

SELECT
    *
FROM
    weather_forecasts;
```

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

![a17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/7b0b6a6c-6f69-faec-5d12-a96f5c49b52c.png)

psqlから抜けます。

![a18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/c127c795-8346-9b8b-fabb-9c6f56a80306.png)

## PostgRESTの作業

本記事ではPostgRESTをPostgreSQLと同じローカルのLinuxホストにインストールします。
[このページ](https://postgrest.org/en/latest/install.html)を参考にして、PostgRESTのバイナリをインストール＆起動します。
Dockerを使う方法もあります。

PostgREST起動時に指定するコンフィグファイル例

```sample.conf

db-uri = "postgres://postgres:secret@localhost:5432/sample_db"
db-schema = "public"
db-anon-role = "postgres"
```

起動コマンド例

```

postgrest sample.conf

```

起動画面

![710.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/1e20fff5-5b06-4881-9373-ef23fb3f3e9f.png)

postgrestコマンドを起動するだけで、PostgreSQLのスキーマを読み取ってAPIエンドポイントを自動生成してくれます。

ブラウザで http://localhost:3000/weather_forecasts にアクセスし、weather_forecastsテーブルのデータを見てみると、以下のように表示されました。

![720.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/cba1b759-8dc8-2e80-49b5-1e56a90cb434.png)

# PostgRESTサーバーを外部公開する

[この記事](https://qiita.com/kanedaq/items/4c3d37d278e674df6e14)のhttpの手順を行って、先程ローカルで起動したPostgRESTサーバー（ポート3000）を外部公開（ポート13001）しました。記事内の動作確認用Webサーバー（python3 -m http.server 3001）の起動は不要です。
なお、本記事ではhttpsは使用しなかったので、Caddyの手順は行いませんでした。

外部からREST APIにアクセスできるか、ブラウザで確認してみます。
VPSのドメインが yourdomain.com であれば、アクセス先は http://yourdomain.com:13001/weather_forecasts となります。

以下のようにリバースSSHポートフォワーディングを利用して、ブラウザからローカルのPostgRESTのAPIを呼ぶことが出来ました。

![730.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/935590fe-507b-2200-6556-46ab56bbdd41.png)

# Querierでアプリを開発する

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

## サイドメニュー「連携データ」での作業

サイドメニューから「連携データ」を選択し、データソースを新規作成します。下図のように、

- 表示名：sample_restapi
- データタイプ：restapi
- baseurl：http://yourdomain.com:13001

としました。

![2010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/520688c7-34cc-f12c-bd21-4849ee20635d.png)

## サイドメニュー「アプリ一覧」での作業

サイドメニューから「アプリ一覧」を選択し、アプリを新規作成します。以下のように、アプリ名をweather_forecasts_restapiとしました。

![2020.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/b74ee511-eb63-ebca-d2e7-bab295af8011.png)

アプリ名の右側の三点ボタンから「編集」を選択し、アプリの編集画面に進みます。

### データフローを4つ作成

下図のように、SQLのSELECT文、INSERT文、UPDATE文、DELETE文に該当する4つのデータフローを作成することにします。

![760.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/b0612d8b-7707-4700-7f1e-ba8cd60703bb.png)

4つ共通の設定として、「データソース＝連携データで作成したsample_restapi」にします。

![2030.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/f921907c-6894-3635-5565-6efe375ac3e9.png)

以下、データフローからinput_id、input_dt、input_temperature_c、input_summaryの4つのインプットコンポーネントを参照しますが、これらは後の作業で作成します。

#### SELECT文のデータフロー

名前を「df_select_weather_forecasts」にしました。
「オプションの入力」は、PostgRESTの仕様に従い、

- メソッド：GET
- URL：/weather_forecasts
- URLパラメーター：order  id.asc

としました。URLパラメーターで、id列の昇順でソートするよう指定しています。

![2040.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/380a055e-14c3-6176-4b0c-f9d8ab79d6ca.png)

#### INSERT文のデータフロー

名前を「df_insert_weather_forecasts」にしました。
「オプションの入力」は、PostgRESTの仕様に従い、

- メソッド：POST
- URL：/weather_forecasts
- データ：JSON

```json

{
    "id":{{ input_id.value }},
    "dt":"{{ input_dt.value }}",
    "temperature_c":{{ input_temperature_c.value }},
    "summary":"{{ input_summary.value }}"
}
```

としました。

![790.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/2f172b8d-03c9-7d0f-286d-ee5ce58ab71d.png)

下にスクロールして、「成功時のトリガーを設定する」に「df_select_weather_forecasts」を設定します。
この設定を行うと、SQLのINSERT文が成功したら引き続きSELECT文が自動実行され、画面のテーブル表示が自動更新されます。

![2050.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/4dabf223-98ca-f4d9-3846-4a181e9b7674.png)

#### UPDATE文のデータフロー

名前を「df_update_weather_forecasts」にしました。
「オプションの入力」は、PostgRESTの仕様に従い、

- メソッド：PATCH
- URL：/weather_forecasts
- データ：JSON

```json

{
    "dt":"{{ input_dt.value }}",
    "temperature_c":{{ input_temperature_c.value }},
    "summary":"{{ input_summary.value }}"
}
```

- URLパラメーター：id  eq.{{ input_id.value }}

としました。

![800.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/3ff28540-97b4-7a7e-a322-9b60d410c8e3.png)

下にスクロールして、「成功時のトリガーを設定する」に「df_select_weather_forecasts」を設定します。
この設定を行うと、SQLのUPDATE文が成功したら引き続きSELECT文が自動実行され、画面のテーブル表示が自動更新されます。

![2060.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/6e554103-d359-723d-b513-b1d4f2dd7e85.png)

#### DELETE文のデータフロー

名前を「df_delete_weather_forecasts」にしました。
「オプションの入力」は、PostgRESTの仕様に従い、

- メソッド：DELETE
- URL：/weather_forecasts
- データ：NONE
- URLパラメーター：id  eq.{{ input_id.value }}

としました。

![810.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/46ee7adc-5d61-6788-4971-8e37d8d4bb8b.png)

下にスクロールして、「成功時のトリガーを設定する」に「df_select_weather_forecasts」を設定します。
この設定を行うと、SQLのDELETE文が成功したら引き続きSELECT文が自動実行され、画面のテーブル表示が自動更新されます。

![2070.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/31860b8b-9b25-a403-7e60-ad192f45d723.png)

以上でデータフローの作成は完了です。

### コンポーネントの配置と設定

#### カラムコンポーネント

画面右側からコンポーネントタブに行き、カラムコンポーネントを下図のようにドラッグ＆ドロップします。

![2080.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/4e5895b7-008d-ae2a-55ef-5c281b0c7ae1.png)

カラムコンポーネントの左側を広めにします。

![840.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/06bbd0ca-d920-5e7b-3a0d-d1349f6a879c.png)

#### テーブルコンポーネント「table1」

コンポーネントタブに行き、テーブルコンポーネントを下図のようにカラムコンポーネントの左側にドラッグ＆ドロップします。

![2090.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/43018ea4-90bc-0f2a-c3b4-67912ba45f16.png)

![860.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/e3d5b55e-63be-333b-c971-d5e79efaca38.png)

エディタータブに行き、データに以下を入力してSELECT文のデータフローを設定します。

```

{{ df_select_weather_forecasts.data }}
```

![870.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/027e93e1-d4e4-cd92-8039-8fb27ac3e2df.png)

テーブルコンポーネントのカラム（列）が古いままですが、アプリ編集を一旦終了し、再び開き直してデータフロー「df_select_weather_forecasts」を実行したら更新されました。

![875.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/0b4e97c0-bbc4-56c3-6273-8f435c2e9b5f.png)

![880.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/78cea2f7-78db-a517-abdf-47d2b3ec454d.png)

#### インプットコンポーネント「input_dt」

コンポーネントタブに行き、インプットコンポーネントを下図のようにカラムコンポーネントの右側にドラッグ＆ドロップします。

![2100.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/c6b9f7d5-bfa2-7fff-86c5-07e38ba3f66e.png)

エディタータブに行き、以下のように設定します。

- ウィジェット名：input_dt
- ラベル：date
- DefaultValue：

```DefaultValue

{{ table1.selectedRow.data ? table1.selectedRow.data.dt : '' }}
```

- 必須：オン

![2110.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/60f47456-42b1-2b5b-3344-107e6a1eee09.png)

DefaultValueにtable1のデータを指定したので、table1の別の行を選択すると値がinput_dtに反映されます。

![2120.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/69126370-d580-9333-02a2-bde49843def8.png)

#### インプットコンポーネント「input_id」

コンポーネントタブに行き、インプットコンポーネントを下図のようにinput_dtの下にドラッグ＆ドロップします。

![2130.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/adcd45f2-1ae9-c8ca-95e3-bb26a09e33c4.png)

エディタータブに行き、以下のように設定します。

- ウィジェット名：input_id
- ラベル：id
- DefaultValue：

```DefaultValue

{{ table1.selectedRow.data ? table1.selectedRow.data.id : '' }}
```

- 必須：オン

![2140.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/836efa37-140a-70f2-ef43-7b6730a4c3cf.png)

#### インプットコンポーネント「input_summary」

コンポーネントタブに行き、インプットコンポーネントを下図のようにinput_idの下にドラッグ＆ドロップします。

![2150.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/15867702-a949-9fca-753e-9f511cf45692.png)

エディタータブに行き、以下のように設定します。

- ウィジェット名：input_summary
- ラベル：summary
- DefaultValue：

```DefaultValue

{{ table1.selectedRow.data ? table1.selectedRow.data.summary : '' }}
```

- 必須：オン

![2160.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/db62a14e-c4e9-601a-5aba-7155ef212b77.png)

#### インプットコンポーネント「input_temperature_c」

コンポーネントタブに行き、インプットコンポーネントを下図のようにinput_summaryの下にドラッグ＆ドロップします。

![2180.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/418bb273-cab9-02b3-824d-d271ad329882.png)

エディタータブに行き、以下のように設定します。

- ウィジェット名：input_temperature_c
- ラベル：temperature
- DefaultValue：

```DefaultValue

{{ table1.selectedRow.data ? table1.selectedRow.data.temperature_c : '' }}
```

- 必須：オン

![2170.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/be24db3a-abd3-dca5-4ec2-fa7cc7d28740.png)

#### ボタンコンポーネント「button_select」

コンポーネントタブに行き、ボタンコンポーネントを下図のようにtable1の下にドラッグ＆ドロップします。

![1010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/692a2e28-ad64-1da1-b546-34e324bb976c.png)

エディタータブに行き、以下のように設定します。

- ウィジェット名：button_select
- ラベル：読み直し
- データフロー：df_select_weather_forecasts

![2190.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/bc55d9eb-9f3f-c8e5-d91b-a01965b255ab.png)

#### ボタンコンポーネント「button_insert」

コンポーネントタブに行き、ボタンコンポーネントを下図のようにinput_temperature_cの下にドラッグ＆ドロップします。

![980.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/3f41d535-1b61-8386-f437-ef46af797748.png)

エディタータブに行き、以下のように設定します。

- ウィジェット名：button_insert
- ラベル：新規登録
- データフロー：df_insert_weather_forecasts

![990.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/a5c82ab6-942d-f0c3-c8cc-0cda6d0991ae.png)

それでは存在しないデータを新規登録してみましょう。
インプットコンポーネントに適当な値を入力して、以下の画面で新規登録ボタンをクリックします。

![1030.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/7a89c2b2-00d3-7bb3-7f7b-557ec61f8c24.png)

以下のように、右上にdf_insert_weather_forecastsが成功したメッセージが表示さました。
また、今回のケースではテーブルコンポーネントに16ページ目が追加されて、df_insert_weather_forecastsに続いてdf_select_weather_forecastsが自動実行された様子です。

![2210.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/f8182b57-5a47-52b6-bb21-6cf7c4923935.png)

その16ページ目を表示させると、新規登録したデータが見えました。

![2220.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/ee0bc4b0-3dfe-4037-cfc9-e7aa4dfc2d30.png)

#### ボタンコンポーネント「button_update」

コンポーネントタブに行き、ボタンコンポーネントを下図のようにbutton_insertの下にドラッグ＆ドロップします。

![1050.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/145203d1-f935-54ff-eb09-d13b912caa80.png)

エディタータブに行き、以下のように設定します。

- ウィジェット名：button_update
- ラベル：行更新
- データフロー：df_update_weather_forecasts

![2230.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/1c7cea72-a994-aa11-1e0a-f751d40c474f.png)

それでは先程新規登録したデータを更新してみましょう。
table1で先程のデータを選択後、インプットコンポーネントのid以外の値を適当に変更して、以下の画面で行更新ボタンをクリックします。

![2240.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/298eee27-f66e-5109-cd74-816db6fc9156.png)

以下のように、右上にdf_update_weather_forecastsが成功したメッセージが表示さました。
また続いてdf_select_weather_forecastsも実行され、テーブル表示が自動更新されました。

![2250.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/0b5c6bb4-ef25-cd50-4c0d-dc9a18e77e6c.png)

#### ボタンコンポーネント「button_delete」

コンポーネントタブに行き、ボタンコンポーネントを下図のようにbutton_updateの下にドラッグ＆ドロップします。

![1090.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/c230f4a7-03bb-789c-df50-0499afaecbb6.png)

エディタータブに行き、以下のように設定します。

- ウィジェット名：button_delete
- ラベル：行削除
- データフロー：df_delete_weather_forecasts

![2260.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/bf96aa9c-2032-aa18-b5f7-6054608e6057.png)

それでは先程更新したデータを削除してみましょう。
table1で先程のデータを選択後、以下の画面で行削除ボタンをクリックします。

![2270.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/c7917300-63f0-8c50-a207-7397cbca5074.png)

以下のように、右上にdf_delete_weather_forecastsが成功したメッセージが表示さました。
また続いてdf_select_weather_forecastsも実行され、今回のケースではテーブルコンポーネントから16ページ目がなくなりました。

![2280.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/ef5e3af5-89f1-1c01-0b5a-cdd631b7ea1a.png)

以上、ひと通りCRUD機能を実装できました。
BIツールではできなかった、データの挿入・編集も可能でした。

# 使ってみての感想

これはエンジニア向けのツールですね。
ローコードなので、コードを書ける分ノーコードよりできることが多く、YesCoderにも受け入れられそうです。
UIをドラッグ＆ドロップで構築できて、コードも追加できるので、かつてのDelphiを思い出しました。

共有データベースとQuerierを連携させれば、共有データベースを通じてYesCodeアプリとも機能連携できそうです。
まず共有データベースをしっかり作り、Querierで作れる機能はサクッと作って工数削減し、複雑な機能だけYesCodeで開発してQuerierと機能連携させるイメージです。
良いと思いますねー。機会があれば、ぜひ業務で使いたいです。
国産ツールなので日本語でサポートが受けられるのも、ありがたいですね。