まだプログラマーですが何か?

プログラマーネタ中心。たまに作成したウェブサービス関連の話も https://twitter.com/dotnsf

タグ:nocode

マーメイド記法を勉強している中で生じたアイデアを実装したら、なんとなくノーコード/ローコードっぽい仕上がりになり、自分で使っていても便利に感じたので公開して紹介することにしました。


【マーメイド記法とは】
最初に「マーメイド記法」について紹介します。マーメイド記法とは「特定のルールでテキストを記述することでフローチャート図を作る」ための記述ルールです。マークダウン記法の一種ですが、実際にマークダウンの中に含める形で使うこともできるようなサービスもあります。有名どころでは今年のバレンタインデーに GitHub 内のマークダウンファイル(.md)内にマーメイド記法で記述された部分があると、フロー図に変換して表示されるようになりました。

例えばこんな内容を含むマークダウンファイルを GitHub にコミットします(1行目はマークダウンそのものですが、3行目の ``` (バッククォート3つ)から ``` までの部分がマーメイド記法で書かれています。後述しますが、もう少し情報量を増やした書き方もあります):
2202110601

(↑なんとなくわかりますかね? AからB、AからC、BからD、CからD、という4つの流れが定義されているものです。先頭行の "graph DB;" は「フロー図を上から下(TopDown) に描く」という意味です)

そしてコミットされたファイルをブラウザで GitHub から見ると、マーメイド記法で書かれた部分がこのようにフロー図に変換されて表示されます:
2202110602



このマーメイド記法はウェブアプリケーション設計時の「画面遷移の定義」の表現に使えると思いました。例えばこんな感じのウェブアプリケーションの画面遷移を考えた時に・・・
 ・最初にログイン画面
 ・ログイン後にトップ画面
 ・トップ画面からA、B、Cの3つの画面に遷移できる

マーメイド記法だとこのように表現できると思ったのです:
```mermaid
  graph TD;
  Login --> Top;
  Top --> A;
  Top --> B;
  Top --> C;
```

また上でも少し触れたのですが、このマーメイド記法はかなり単純な最小限の情報しか含んでいませんが、もう少し情報量を増やしてこのような書き方もできます:
```mermaid
  graph TD;
  Login["ログイン"] --"/"--> Top["トップ"];
  Top --"/info"--> A["商品情報"];
  Top --"/download"--> B["ダウンロード"];
  Top --"/about"--> C["○○について"];
```


このマーメイド記法をフロー化するとこのようになります:
2022110503


A や B といったノードの名前そのままではなく、["~~"] で括られた部分がノードの表示用の名称として表示されています(一度 Top["トップ"] と表示名を定義しておくことで、2回目からはただ Top と書くだけでよくなります)。加えて矢印にも名前が付けることで、なんとなく UI のないワイヤーフレームっぽくなりました。どのページからどのページへ、なんという URL パスで進むようになるか、というのが視覚化できます(上の図の「ログイン」ページに相当する URL パスがないのでまだ不完全ですが、詳しくは後述します)。


マーメイド記法はフロー図だけでなく、色々な種類のグラフを描くことができます。ただマーメイド記法そのものの書き方についてはこのブログエントリの目的ではないので、他のサイトでの紹介を参照いただきたいです。私自身はこのページに多くお世話になりました:
https://zenn.dev/okazuki/articles/learning-mermaid


【アイデアと、実装して作ったツール】
このマーメイド記法を使って作ったファイルを使って、以下のような3つの機能を作れないだろうか、というアイデアを思いつきました:
 (1)ワイヤーフレームの全画面を表示できるようなウェブアプリ化
 (2)ワイヤーフレームの中で DB 定義が必要と思われる部分を抜き出して API 化
 (3)(おまけ)マーメイド記法で書かれた部分をフロー図化

(1)は上で示したようなフローを実現できるような最小限のウェブアプリを、マーメイド記述されたファイルから、各ページの URL パスをそのまま再現する形で自動生成する、というものです。 各ページの UI は最小限ですが、例えば上の例であれば「ログイン」ページを表示すると「トップ」ページに遷移できるようなリンクがあり、「トップ」ページを表示すると「商品情報」、「ダウンロード」、「○○について」という3つのリンクがあって、それぞれのページに繋がっている、というものです。フロー定義から画面実装までを自動化して、生成された HTML テンプレートをカスタマイズすることで見た目も定義できるようにする、というものです。

(1)についてはもう1つ、(2)にも関わるのですが例えばマーメイド記述された中に "/(複数形)""/(単数形)/:id" というフォーマットに合致する2つのパスが含まれていた場合は、前者を一覧ページ、後者を詳細ページとみなして、それに近い UI を用意する、という機能を持たせました。例えば、マーメイド記述が
```mermaid
  graph TD;
  Login["ログイン"] --"/"--> Top["トップ"];
  Top --"/users"--> A["ユーザー一覧"];
  A --"/user/:id"--> B["ユーザー"];
    :
```

のようになっていた場合、単に「ユーザー一覧」画面と「ユーザー」画面がリンクでつながっているのではなく、「「ユーザー一覧」は「複数のユーザーの一覧画面」」で「「ユーザー」画面は「ユーザー ID が :id となる単数のユーザーの詳細画面」」であることを識別できるようにしました。自動生成される画面も単なるリンクで繋げるのではなく、「ユーザー一覧」画面にはユーザーが複数表示され、それぞれのユーザーがクリックできるようになっていて、クリックするとクリックしたユーザーの詳細ページに遷移する、というものです。

そして(2)の機能は、この「ユーザー一覧」画面と「ユーザー詳細」画面があるということは「ユーザーのデータを扱う必要がある」と判断し、ユーザー情報を CRUD できるような API (と Swagger ドキュメントと DDL)を自動生成する機能です。具体的には、
 ・POST /user (一人のユーザーを新規作成する)
 ・POST /users (複数のユーザーをバルクインサートする)
 ・GET /user/:id (一人のユーザーの情報を ID を指定して取得する)
 ・GET /users (複数のユーザーの情報をまとめて取得する)
 ・PUT /user/:id (ID を指定したユーザーの情報を更新する)
 ・DELETE /user/:id (ID を指定したユーザーを削除する)
 ・DELETE /users (複数のユーザーをまとめて削除する)
という7つの CRUD API を作る、というものです。加えてこれらの API のデータ格納先となるテーブルの DDL 定義(id と name の2列だけですが・・)と、実際に動作確認できる Swagger API ドキュメントも作成します。


最後におまけの(3)、これはマーメイド記法で表記した内容を GitHub にコミットしなくても見ることができるよう、ローカルでマーメイドファイルを表示できるようにするツールもあると便利だったので、自分用に作ってみました。

こうしてできあがったのがこのツールで、現在は Node.js 向けソースコードを GitHub で公開しています:
https://github.com/dotnsf/web-template


【ツールの使い方】
このツールを使う場合は、まずは Node.js の環境を用意する必要があります。必要に応じてインストールしてください:
https://nodejs.org/ja/


次に git でソースコードを clone して、"npm install" で動作に必要なライブラリをインストールします:
$ git clone https://github.com/dotnsf/web-template
$ cd web-template
$ npm install

そしてアプリケーションや API サーバーのソースコードを生成するためのマーメイドファイルを用意します。ソースコード内に mermaid_sample.md というファイルが含まれていますので、これをそのまま使っても構いませんし、自分で用意しても構いません。

ただ自分でマークダウンファイルを用意する場合は次の点に注意してください:
  • 各ノード(ページ)の表示名を定義する場合は ["~~"] という形で記述する(マーメイドのルールでは ("~~") など、丸括弧で括っても正しく判断されますが、このツールを使う場合は ["~~"] という四角括弧で表示名を括ってください。
  • 全てのノート(ページ)を表示するための URL パスが定義できているようにマーメイドファイルを用意してください。

例えば上で紹介したこのマーメイドファイル例:
```mermaid
  graph TD;
  Login["ログイン"] --"/"--> Top["トップ"];
  Top --"/info"--> A["商品情報"];
  Top --"/download"--> B["ダウンロード"];
  Top --"/about"--> C["○○について"];
```

は一番上にある Login["ログイン"] ページを表示するための URL がどこにも定義されていません(ので、このまま実行してもエラーになります)。マーメイドファイルのどこかに(例えば以下の例のように)このログインページへの URL パスを追加する必要があります(mermaid_sample.md ファイルは初めからこのようになっています):
```mermaid
  graph TD;
  Login["ログイン"] --"/"--> Top["トップ"];
  Top --"/info"--> A["商品情報"];
  Top --"/download"--> B["ダウンロード"];
  Top --"/about"--> C["○○について"];
  Top --"/login"--> Login;
```

最後にトップページからログインページに遷移するためのパス /login を定義する行を加えました。これで全てのノード(ページ)の URL パスが定義されたことになります。もし実際のアプリケーションではトップページからログインページへのリンクが不要であれば、生成されたトップページからログインページへのリンクボタンを手動で削除してください(具体的には以下で説明します)。

なお最初の状態のマーメイドサンプルファイル(mermaid_sample.md)の内容は以下のようになっています:
# mermaid

```mermaid
  graph TD;
      Login["ログイン"] --"/"--> Top["トップ"];
      Top --"/items"--> Items["アイテム一覧"];
      Items --"/item/:id"--> Item["アイテム詳細"];
      Top --"/users"--> Users["ユーザー一覧"];
      Users --"/user/:id"--> User["ユーザー詳細"];
      Top --"/about"--> About["サイト解説"];
      Top --"/login"--> Login;
```

「アイテム一覧(/items)」と「アイテム詳細(/item/:id)」、「ユーザー一覧(/users)」と「ユーザー詳細(/user/:id)」という組み合わせが定義されていることを覚えておいてください。

また、このフローをマーメイド対応のビューワで表示すると、このようになります:
2022110504


マーメイドファイルが用意できたら実際に動かしてみましょう。まず(1)のワイヤーフレームの全画面を表示できるようなウェブアプリを作ってみます。この場合はソースコード内の web.js を使って、以下のように実行します:
$ MERMAID=mermaid_sample.md node web

実行時に MERMAID という環境変数を指定しています。この環境変数にマーメイドファイル名を指定します(上の例では mermaid_sample.md ファイルを指定しています)。

マーメイドファイルに問題もなく、正しく実行された場合は一瞬で実行が完了し、web/ というフォルダに実行結果が生成されています。実際に生成された結果を確認するには web/ フォルダで "npm start" を実行します:
$ cd web
$ npm install
$ npm start

成功すると 8080 番ポートでウェブアプリケーションが待ち受けているので実際にアクセスして動作を確認してみましょう。まずログインページにアクセスするには(マーメイドファイル内で)/login へアクセスすることでログインページが表示されるよう定義していたので、ウェブブラウザを起動して "http://localhost:8080/login" にアクセスしてみます:
2022110505


本来であれば「ログイン」ページには ID とパスワードを入力するフィールドがあって、、というものだと思いますが、残念ながらそこまでは再現できていません。ただこのページには「トップ」と書かれたボタンがあり、このボタンをクリックすることで(マーメイドファイルの中で定義されていたように)トップページへ遷移するようにできています:
2022110506


トップページは↑のようになります。マーメイドファイルではトップページから「アイテム一覧(/items)」、「ユーザー一覧(/users)」、「サイト解説(/about)」、「ログイン(/login)」という4つのページへのリンクが定義されていたので、それらがそのまま4つのボタンになっています。正しく再現できています。

試しに「アイテム一覧」ボタンをクリックすると以下のようになります:
2022110507


先ほどまでのページとは少し違う画面になりました。これはアイテム一覧のページ(/items) がアイテム詳細(/item/:id) のページと繋がっていて、これらの URL パスのルール性から「個別のページ」ではなく「item の一覧」のページであると判定された結果です。その結果、表形式で item の一覧(id と名前だけですけど)が表示されています。そしてこれらのいずれかをクリックすると(例えば id = 0 の一番上のデータをクリックすると)/item/0 へ遷移し、詳細画面が表示されます(トップ画面からユーザー一覧ボタンをクリックした場合も同様の画面遷移となります):
2022110508

※(注意)
この「一覧」と「詳細」の両ページの存在を確認するには、マーメイドファイル内の URL パスで
- /(複数形)
- /(単数形)/:id
という2つの URL パスが定義されていることが条件なのですが、この「複数形」の表現には注意が必要です。

"user" の複数形は "users" で、"item" の複数形は "items" で何も問題はないのですが、例えば "category" の複数形は注意が必要です。英単語として正しくは "categories" となりますが、本ツールでは単に "s" を付けるだけの "categorys" と定義する必要があります。"information" も(正しくは複数形が存在しない英単語ですが、もし information の一覧ページを作りたいのであれば)"/informations" という URL パスで一覧ページを定義する必要がある、という点に注意してください。
※(注意ここまで)


一方、トップ画面から「サイト解説」や「ログイン」ボタンをクリックした場合は、遷移先が一般的なページ画面であると認識され、表形式ではなく(リンクがある場合は)ボタンが表示される画面となります(下図は「サイト解説」ボタンを押した場合):
2022110509


・・・と、このように web.js はマーメイドファイルを指定するだけで、その内容からここまでのページ遷移を実現するウェブアプリケーションが自動生成できました。実際に詳細なワイヤーフレーム画面を作りたい場合は生成されたフォルダの views サブフォルダや public サブフォルダに HTML テンプレートや CSS, JavaScript ができているので、これらをカスタマイズすることでデフォルトの生成画面を(HTML や CSS の知識だけで)カスタマイズできる、というものです。


次に同じマーメイドファイルから(2)の API を作ってみます。(1)でも紹介しましたが、今回使用するマーメイドファイルには「ユーザー(user)」と「アイテム(item)」という2つのデータを対象に一覧表示したり、詳細表示するページが含まれていました。ということは user と item の2つはデータベースに格納して読み書き更新削除する可能性があるデータ、という推測ができることになります。

この推測通りに動くかどうかを実際に使って確認してみます。元の web-template フォルダで今度は api.js を以下のように実行します:
$ MERMAID=mermaid_sample.md node api

この実行結果は api/ フォルダに出力されます。今度も(1)と同様に api/ フォルダに生成されたコードを実行してみます:
$ cd api
$ npm install
$ npm start

成功すると 8081 番ポートで API アプリケーションが待ち受けており、また /_doc/ という URL パスで Swagger ドキュメントが稼働しています。実際に Swagger にアクセスして動作を確認してみましょう。"http://localhost:8081/_doc" にアクセスしてみます:
2022110510

2022110511


↑のように、item および user の情報を CRUD できる API と、その Swagger ドキュメントが用意されました。データはメモリに格納するので再起動するまでの間であれば実際にデータを保存したり、変更したり、削除したり、読み出したりすることができます。マーメイドファイルからデータ操作が必要な要素を見つけ出して API 化する(ためのソースコードを出力する)、という機能が実現できていることがわかります。 プロトタイピング目的であればこれだけでもかなり使えるところまで設計を可視化することができると思っていますが、(1)で紹介した web.js でマーメイドファイルからページ遷移機能と、(2)で紹介した api.js で API サーバーを両方作った上で、一覧ページと詳細ページの部分だけ API 連携するようカスタマイズすれば、細かな見た目以外のかなりの部分を実現できるプロトタイピングがほぼノーコード/ローコードで実現できると感じています。


最後におまけの(3)について紹介します。(3)はカスタマイズしたマーメイドファイルが、想定していた通りの正しいフローになっているかどうかを確認するためのマーメイド・プレビューワーとしてのアプリケーションです。(1)・(2)同様に環境変数 MERMAID にマーメイドファイルを指定して、以下のように実行します:
$ MERMAID=mermaid_sample.md node preview

成功すると 8000 番ポートでプレビューワーのアプリケーションが待ち受けています。実際にアクセスして動作を確認してみましょう。"http://localhost:8000" にアクセスしてみます:
2022110512


マーメイドファイルのプレビューができました。これで正しい(自分の想定通りの)ワイヤーフレームがマーメイドファイルとして実現できているかどうかを(GitHub などにコミットしなくても)事前に確認することができます。おまけツールではありますが、(1)や(2)を実行する前に何度か使うことになる利用頻度の高いツールであるとも思っています。


【まとめ】
もともとはウェブアプリのデザインとワイヤーフレームを効率よく作るためのプロトタイピングツールを作ろうとしていたのですが、マーメイドファイルとの相性がよく、データ API まで作れるようになったことで、ノーコード/ローコードツールともいえるかな、という形になりました。実際にはここで紹介していないパラメータを使うことで CRUD API を本物のデータベースと接続して作ったり、UI 部分も(デフォルトでは Bootstrap ベースで作るのですが)Carbon や Material デザインにしたり、ということもできるようには作っています。 興味あるかたは公開されているソースコードや README を見て試してみてください。

「複数人でプログラミングを体験する」ための環境を作ることになった場合、その環境をどう実現すればいいかを考えました。
computer_mob_programming


より具体的にはこんな状況・前提だと思ってください(余談ですが DX の影響なのか、業務でこういう需要を耳にする機会が増えているように感じてます):
- 複数人でアプリ開発(プログラミング)体験を行いたい
  - 参加者は1チーム5~6人程度
  - 参加者は普段 Windows を使っている。Mac, Linux の経験はほぼゼロ
  - 参加者はコマンドプロンプトなどの CLI は普段使っていない
  - 参加者はプログラミングに関してはほぼ初心者
- チームで1つのアプリを作って動かす、という体験をしたい
- 体験期間は半日、長くて1日
- 参加者の PC に何かをインストールしたり、アカウントを作ったり、設定したりする場合、作業できるのは当日
  - 参加者 PC 以外の Linux サーバーなどに主催者が事前準備するのは自由
- 全員オンライン参加、zoom などのオンラインツールの利用に問題はない


最後の前提は必須ではないですが、昨今だとどうしてもこの条件になるかなあ、ということで加えています。


この状況下でどういう仕組を用意すれば、目的に会ったプログラミング体験ができるかを考えます。


候補案1
「とりあえず正攻法でやってもらう」方法です。ソースコードは git などでリポジトリ管理して(必要であれば事前にサンプルを用意して)、各自はリポジトリから clone したソースコードを画面共有を併用しながら手元で編集して動かしてもらう。環境が許せば Visual Studio Code の LiveShare なども使って共同編集する。。

・・・これが本来のスジであることは重々承知しているし、将来的に役立てることを意識するならこの形を学ぶべきだとは思っています。ただプログラミング初心者相手に半日~1日でここまでやるには少しハードルが高すぎる気がしています。環境準備段階でのハードルの高さもありますし、git も教えないといけないし、LiveShare 使うならアカウントから準備しないといけないし、その上でほぼ未経験のプログラミングをオンラインで・・・ 何を作るかにもよりますが、Hello World 程度すら厳しいかも。。

#おまけとして、業務においてはこの手の「管理者権限が必要な作業」自体が実施上のリスクとなる可能性があることを経験談として触れておきます。


候補案2
参加者がそこそこ Linux に詳しい人だったら、Linux サーバーにサンプルを含むソースコードを集める形にして、全員が個別に SSH や VNC でログインして vi でプログラミングすればよい、です(同時編集によるコンフリクトはいったん目をつぶりますw)。同じサーバーでアプリを動かせば、それぞれがウェブブラウザで動作確認もできます。

でも今回、この形で行うにはハードルが高すぎます。普段から SSH やコマンドプロンプトを使うような人ではなく、ましてやキーバインドにクセのある vi を使わせるのは厳しそうです。

手段の1つとして「SSH でログインして nano エディタを使う」ことや「Linux に X Window まで導入した上で、VNC でログインして簡易テキストエディタを使う」も考えられます。これらはありっちゃあり、懸念があるとすれば慣れない CLI や Linux での操作でしょうか。nano エディタも vi や Emacs ほどクセはありませんが、Linux コマンドを無視することもできませんし、CTRL キーや ALT キーと組み合わせてのメニュー操作は慣れるまでは苦労するかも、という印象です。

その辺りの苦労も体験の一部とみなしてやってもらう、という案は相手次第ではあり、かな。。


ここまで書いておいてアレですが、個人的にはここまでの案1&2は現実的ではないかな、と考えています。オンラインでなければまだしも、オンラインでこの慣れてないはずの作業のサポートをするのはかなり難しそうという印象を持っています。理想どおりに実施するのことがかなり厳しそう・・・


候補案3
いわゆるローコード・ノーコード環境を事前に Linux サーバーに用意して、この環境を使う方法です。

これは目的に対する解答になっていると思います。Linux に例えば Node-REDScratch などをインストール&起動しておいて、参加者は画面共有しながらウェブブラウザで(CLI ではない、ここがでかい!)アクセスしてコーディング作業を行う、というものです。なんといっても参加者の PC に何かを事前にインストールする必要がない(=準備段階のリスクが低い)点がポイントです。ローコードなのでプログラミング開始時の敷居が低く、1日でもそこそこ学べるものだと思っています。

懸念が2つあるとすれば、この環境が1つは共同作業に適したツールかどうかの判断や対応が必要になる点と、もう1つはやはりどうしてもできることの制限があることです。ローコードであるが故に「ループ」や「条件分岐」といったコーディングの基礎のようなことを行う選択肢が少なかったりするわけです(ループができないとは言わないけど「整数配列をその数だけループさせながら加算する」とかは Node-RED では難しい)。動くものは作れるかもしれないけど、プログラミング体験という当初の目的を達成できるものになるかどうか、が鍵だと感じました。


候補案4
実はいま個人的にはこれが一番いいかも、と考えているのが、この候補案4です。概要はこんな感じ:
(1) サンプルを含むソースコードを事前に Linux サーバーに用意する
(2) 同サーバーに Eclipse Orion をインストールする
(3) 参加者はウェブブラウザで Eclipse Orion にアクセスして、サーバーのソースコードを直接編集
(4) 誰か一人(主催者でもよい)がサーバーでアプリを起動して動作確認

(1) のサンプルはあらかじめ最低限動くものを用意しておきます。目的にもよりますが、Hello World 表示だけのウェブアプリでもかまわないと思ってます。

(2), (3) の Eclipse Orion は「オンラインテキストエディタ」です。サーバー上で起動し、サーバー内の特定フォルダ以下のテキストファイル(ソースコード)をオンラインで編集できるようになります。テキストエディタとしての基本機能があるので、便利にコーディング作業をすすめることができます。オンラインエディタは必ずしも Orion エディタでなくてもいいと思ってますが、オープンソースであることや docker 環境下で使える便利さもあっておすすめです。

(4) そして編集したソースコードを使って実際に動かし、可能であれば全員がウェブブラウザで動作も確認する、というものです。

この方法も候補案3同様に、参加者 PC 側での事前準備が不要です。CLI 操作もなく、全て GUI 作業です。Java なり JavaScript なりの実行環境もサーバーだけに事前に用意しておけばいいので参加の負担はありません。実際にコーディングも行うので、内容も(分岐やループから、外部API へアクセスしての AI 体験みたいなことまで)自由度高く設計可能です。

プログラミング環境も、Eclipse Orion インスタンスを1つだけ起動して、全員で同じインスタンスに接続して共同プログラミングしてもいいし、Eclipse Orion インスタンスを複数起動して別々に接続させることで同じテーマで個別にプログラミングすることもできます。純粋なプログラミング環境を比較的容易に準備する方法と考えます。


こちらの懸念はあらかじめ用意しておくサンプルをどうするかと、候補案3と異なり「実際にプログラミングを行う(しかも半日~1日で)」ことになる点です。データベースを使うかどうかなど、サンプルに合わせたカリキュラムの検討が必要だと思っています。その代わり「プログラミング体験」という目的に合っていて、「まず一度体験してもらう」ための案としては自由度も高くて悪くない、と思っています。

 

このページのトップヘ