ローコード開発プラットフォーム「ToolJet」で爆速Webアプリ開発

# :rocket: ToolJetの構築・操作

## :airplane_small: ToolJetとは

オープンソース（AGPL 3.0）で開発されているローコード開発プラットフォームです。

[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/8852740b-5923-9056-4edb-4fa66a9c7593.png)](https://www.tooljet.com/)
様々なデータソースに接続することが可能で、画面デザインもドラッグ&ドロップで簡単に作成することができます。
これまでローコードと呼ばれるツールには多少触れてきました（Oracle Apex、Kintone等々）が、これほど容易にアプリケーションを作ることができるプラットフォームはありませんでした。
かと言ってシンプルなものしか作れないかというと、そうでもなさそうです。
接続可能なデータソースは"MySQL"や"PostgreSQL"などオープンソースのRDBのほか、"Oracle"や"SQL Server"といった商用RDBもOKです。そのほか"Elasticsearch"や"MongoDB"などのデータベース、"Notion"や"Slack"、"AWS S3"などのクラウドサービスにも接続可、もちろんREST APIもイケます。
また至るところにJavaScriptを埋め込むことができるので、ちょっと頑張ればそこそこ高機能なWEBアプリも作れそうです。

ToolJetは[クラウドサービス](https://tooljet.com/signup)としても提供されており、登録さえすればすぐに利用が可能です。
ですが、例えば社内にあるDBのデータを利用したい場合、クラウドサービスから社内へアクセスするにはかなり高いハードルがあるのが一般的だと思います。
そこで、このページでは、ToolJetをDockerを利用して構築する手順、およびToolJetの簡単な操作方法について記載します。

## :whale2:  DockerによるToolJet構築

必要なもの：docker および docker-compose

まず、任意のディレクトリに`docker-compose.yml`および`.env`ファイルを作成します。
```docker-compose.yml
version: '3'

services:
  client:
    tty: true
    stdin_open: true
    image: tooljet/tooljet-client-ce:latest
    container_name: tooljet-client
    restart: always
    env_file: .env
    depends_on:
      - server
    volumes:
      - ./logs:/var/log/openresty/
      - ./certs:/etc/resty-auto-ssl/
      - ./fallbackcerts:/etc/fallback-certs
    ports:
      - 8080:80
      - 8443:443
    command: openresty -g "daemon off;"

  server:
    image: tooljet/tooljet-server-ce:latest
    container_name: tooljet-server
    tty: true
    stdin_open: true
    restart: always
    ports:
      - 3000
    env_file: .env
    environment:
      SERVE_CLIENT: "false"
    command: npm run start:prod
    depends_on:
      - postgres

  postgres:
    image: postgres:13
    container_name: tooljet-db
    restart: always
    ports:
      - 5432
    volumes:
      - ./postgres:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=postgres
```
```.env
# Create .env from this example file and replace values for the environment.
# The application expects a separate .env.test for test environment configuration
# Get detailed information about each variable here: https://docs.tooljet.com/docs/setup/env-vars

TOOLJET_HOST=http://[IPアドレスまたはホスト名]  # 例：http://12.34.56.78、https://yourdomain.com
LOCKBOX_MASTER_KEY=LOCKBOX_MASTER_KEY（32byte）を入力
SECRET_KEY_BASE=SECRET_KEY_BASE（64byte）を入力

# DATABASE CONFIG
ORM_LOGGING=all
PG_DB=tooljet_production
PG_USER=postgres
PG_HOST=postgres
PG_PASS=postgres

# Checks every 24 hours to see if a new version of ToolJet is available
# (Enabled by default. Set 0 to disable)
CHECK_FOR_UPDATES=

# Checks every 24 hours to update app telemetry data to ToolJet hub.
# (Telemetry is enabled by default. Set value to true to disable.)
# DISABLE_APP_TELEMETRY=false

GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=

# EMAIL CONFIGURATION
DEFAULT_FROM_EMAIL=hello@tooljet.io
SMTP_USERNAME=
SMTP_PASSWORD=
SMTP_DOMAIN=
SMTP_PORT=

# DISABLE USER SIGNUPS (true or false). Default: true
DISABLE_SIGNUPS=

# OBSERVABILITY
APM_VENDOR=
SENTRY_DNS=
SENTRY_DEBUG=

# FEATURE TOGGLE
COMMENT_FEATURE_ENABLE=
ENABLE_MULTIPLAYER_EDITING=true

#SSO
SSO_DISABLE_SIGNUP=
SSO_RESTRICTED_DOMAIN=
SSO_GOOGLE_OAUTH2_CLIENT_ID=
SSO_GIT_OAUTH2_CLIENT_ID=
SSO_GIT_OAUTH2_CLIENT_SECRET=
```
※`LOCKBOX_MASTER_KEY`には`openssl rand -hex 32`コマンドを実行して得た値を、`SECRET_KEY_BASE`には`openssl rand -hex 64`コマンドを実行して得た値をそれぞれ入力します。

また同ディレクトリ内に、`logs` `certs` `fallbackcerts` `postgres`ディレクトリも作成しておきます。

その後カレントディレクトリを上で作成したファイル等のあるディレクトリにし、`docker-compose up -d`を実行します。
これで`tooljet-db`コンテナ、`tooljet-server`コンテナ、`tooljet-client`コンテナが作成され起動します。

PostgreSQLコンテナの起動が完了したら、続けて`docker-compose run server npm run db:seed`を実行します。
※`docker logs tooljet-db`を実行し、`database system is ready to accept connections`の表示があればPostgrSQLコンテナの起動は完了しています。

これでコンテナによるToolJetの構築は完了です。ブラウザからアクセス（http://[IPアドレス]）してみましょう。

ログイン画面が表示されます。`dev@tooljet.io`および`password`でログインすることができます。
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/6716cf8d-0ead-ac28-f11b-841c9f248e52.png)
続いて組織名や名前、メールアドレスを入力するよう促されますが、ここは[Skip]でOKです。
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/30efb709-4829-68a0-0e3d-9cab620571ab.png)
以上でToolJetの初期設定は完了です。

## :play_pause: ToolJetでアプリ開発

では構築したToolJetを使って早速アプリを作ってみましょう。

まずはTOPページにある[Create new application]ボタンを押下します。
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/e294a137-37a9-8729-c980-27aa9aaf7ae9.png)
アプリのバージョンを聞かれるのでデフォルト（v1）のまま[Create]ボタンを押しましょう。
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/0e4bc75b-248b-e6cb-342e-92fe2916efe0.png)
開発画面が表示されます。非常にスッキリした画面です。
![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/9e2aad83-4434-668e-3933-7573c4471898.png)
はじめに、右ペインから中央ペインへ[Text]をドラッグ&ドロップしてみましょう。
画面上にテキストエリアが現れます。設定をするため、このテキストエリアの歯車マーク :gear: をクリックします。
![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/56b6caa7-5c09-816b-8ce2-ac3a49aa7247.png)
右ペインに設定画面が表示されます。テキストエリアに表示する内容を"Text"の入力欄に入力します。
![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/9b0069ce-daab-e7b7-a7fa-41136af79864.png)
続けて表示スタイルの設定をします。上部の[Styles]タブをクリックしてください。
![08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/403dbbc3-e15d-4db8-61c9-e2b7c193f313.png)
ここでテキストのサイズやカラーを設定します。
![09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/e272040f-9a42-8950-cbd0-3ac958401da9.png)
アプリ画面となる中央ペインに反映されました。
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/0cf5b98f-b600-4fda-a907-07263035e471.png)
次に右ペインから中央ペインへ[Dropdown]をドラッグ&ドロップします。
中央ペインにドロップダウンが表示されたら、また歯車マーク :gear: をクリックして設定画面を表示させます。
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/39e8b722-fb47-c611-09ad-c563d240e467.png)
"Label"入力欄にはドロップダウン横に表示する文字列を、"Option value"にはドロップダウン選択時の値を、"Option labels"にはドロップダウンに選択肢として表示される文字列をそれぞれ入力します。
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/84e68482-2278-0779-39fe-d4cead997379.png)
これでアプリ画面のドロップダウンに設定内容が反映されました。
![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/6010d96e-ddab-c5ba-d07c-8aedc8bb4a0e.png)
次にデータソースの設定をしてみます。
左メニューで[Sources]をクリックし、"Data sources"横の[ + ]ボタンを押下します。
![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/f0f91368-c16c-aef8-b380-f15683c27d33.png)
表示されるデータソース一覧の中から対象のデータソースを選択します。今回は"Oracle DB"を選択しました。
![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/b2b2245e-ec49-1bfe-5f03-c245f3e8b887.png)
選択したデータソースの設定画面が表示されます。それぞれの項目について値を入力し、入力し終えたら下部の[Test Connection]ボタンを押下します。
![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/5c905e50-4546-bda5-f5cb-8e0cca6a73a1.png)
テスト接続がOKなら[Test Connection]ボタンが"CONNECTION VERIFIED"に変わります。
設定に問題がなくテストもOKであれば[Save]ボタンを押下します。
![17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/013e24bb-fab0-ab79-7386-bbe6b13c50d7.png)
~~ブラウザを更新（[F5]等）すると、~~ データソースとして登録したものが表示されます。
![18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/a568e69d-93cb-14e5-7157-7b597eb43166.png)
登録したデータソースからデータを抽出するためのクエリを作成しましょう。
画面下部"Queries"横の[ + ]ボタンを押下します。
![19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/41b87226-7ac4-2730-7c55-4dbd1067791a.png)
先ほど登録したデータソースが表示されるので、これを選択します。
![20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/49f1ef93-5354-fec9-5bde-ec70162dcdde.png)
ドロップダウンで"SQL mode"を選択します。
![21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/f6fbf153-0a6d-2f9b-45e3-111224368bfb.png)
その下にSQLを記載するスペースが表示されるので、ここにSQLを記載していきます。SQL内では、アプリに配置した各コンポーネントの値を利用することができます。
以下の例では、ドロップダウン"dropdown1"の値をSQL内のパラメータとして利用しています。
SQLを書いたら、正しくデータを取得できるか確認します。[Preview]ボタンを押下してみてください。
（※SQLに他コンポーネントの値を埋め込んでいるときは、Previewの際にそのコンポーネントで値を入力または選択しておく必要があります。例ではアプリ画面上のdropdown1で何かの値を選択しておかなければなりません。）
![22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/9b27a6a2-78cb-14de-4f78-05105cdbebdd.png)
SQLにおかしなところが無ければ下部に結果が表示されます。
![23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/120568aa-6d75-0243-3854-7d144d38fcca.png)
ここまでで問題が無いことが確認できたら、クエリの名前を入力し[Create]ボタンを押下します。
![24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/699be8dd-d7c9-548c-90d2-5bacede0b749.png)

~~ブラウザを更新（[F5]等）すると、~~ 登録したクエリが表示されます。
![25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/8e7da4fa-2563-e383-9006-7169445a0794.png)
ドロップダウンにイベントを設定します。
先に配置したドロップダウンの設定画面を開き、設定画面下部の[+ Add event handler]をクリックします。
![26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/ce801e73-5dc0-c797-2638-8fac43bb3350.png)
表示されたボタンを押下します。
![27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/dba02b90-39ec-6dba-0d62-d13941ed7e7c.png)
イベントの設定画面が表示されるので、必要事項を入力していきます。
ここでは、ドロップダウンで値が選択された（"On select"）際にクエリ（"PM_select"）を実行（"Run Query"）するよう設定しています。
![28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/ef6f31d9-256f-1dcd-fe76-a4cd583dbf85.png)
これでドロップダウンを選択することによりクエリが実行されるようになりました。

次にクエリの結果を表示するためのテーブルを作成しましょう。
"Table"をドラッグ&ドロップでアプリ内に配置し、配置したテーブルの設定画面を開きます。
![29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/5d763a57-094b-4b14-09ac-85361ba64def.png)
"Table data"項目にクエリのデータを設定します。
また"Columns"で各列に表示するデータを設定していきます。デフォルトで"id","name","email"列が作成されるので、これらを修正します。まずは"id"を選択します。
![30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/440439e7-eca4-6596-32f3-23d5b81b79e1.png)
"Column type"は'Default'または'String'を、"Overflow"は'Wrap'を選択します。
"Column name"には列名として表示される文字列を、"key"にはクエリの結果からこの列に表示したい項目名を入力します。
![31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/509cae0e-6922-b144-3fc8-ec8bebf2309c.png)
これを繰り返し、表示したいすべての列の設定をします。[+ Add column]を押下することで列を追加することができます。
![32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/1176ed20-c51d-d4a0-a57d-d5169b09c4d1.png)
すべての列がアプリ上のテーブルにも反映されました。
![33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/472cc67a-e12b-6b7e-493c-d60dacef2ffb.png)
ドロップダウンで何か値を選択してみましょう。
![34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/2a3ef724-05e4-57eb-db5f-15f6e90eb1ed.png)
選択した値に応じたデータがテーブルに表示されました。
![35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/f1d1c079-4acc-a815-2658-4fef3bbc2be1.png)

アプリの作成が完了したら右上の[Release]ボタンを押下します。
![37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/521117bf-cbde-a376-e1fe-30fbd92ac133.png)
続けてその横の[Share]ボタンを押下します。
![38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/c50cb5dc-0231-089d-1c81-5172e13112e4.png)
アプリのURL等の設定画面が表示されます。URLはデフォルトのままでもいいですし任意の文字列を入力しても構いません。[Copy]ボタンでURLをクリップボードにコピーすることができます。
![39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/2f9d85be-6298-ec27-4f94-2058c5f5e697.png)
別のブラウザでコピーしたURLにアクセスすると、作成したアプリを開くことができます。
![40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479194/c90f80f7-d773-93e7-2553-8f1986c180e6.png)

以上、極々基本的なアプリ作成方法でした。
ほかにもいろいろな設定、データ連携ができ、活用可能な範囲はかなり広く感じています。
また操作自体もシンプルで扱いやすいものです。
~~登録した情報が[F5]キーを押さないと画面に反映されないのが玉に瑕ですが~~
あとは、社内で使う場合が多いと思うので、LDAPに対応してほしいところです。
が、これらを踏まえても、個人的にはこれまでで最高に使い易い＆使えるローコードプラットフォームと感じています。