はじめに
先日、私が以前に申請していたDarkのプライベートベータ版に漸く招待されたので、実際に触ってみた感想を述べよう思います。
1. Darkとは?
Darkとは、Ellen Chisa、そしてCircleCIの創業者であるPaul Biggarによって設立された会社で開発されている**「偶発的な複雑さ」を無くし、バックエンドWebサービスを構築するための総合的なプログラミング言語**であり、エディタであり、インフラストラクチャです。呼称するならば、総合的なソフトウェア開発プラットフォームみたいな感じです。Web上にエディタが展開され、そこで全ての開発を行える為、開発ツールやパブリッククラウドと言った多くのテクノロジーを直接触る必要はありません。
また、最大の特徴としてはデプロイレスです。デプロイレスとは、入力したものが即座にデプロイされ、本番環境ですぐに使用できます。Darkはインタープリタをクラウドで実行され関数またはHTTP/イベントハンドラで新しいコードを作成すると、抽象構文ツリーの差分(エディターとサーバーが内部で使用するコードの表現)をサーバに送信し、次にそのコードを実行します。その為、デプロイメントはデータベースへの僅かな書き込みで済む為、瞬時且つアトミックです。この様に、デプロイを可能な限り最小化する事で最大50msの高速デプロイを実現しています。
※デプロイレスに関する詳細は本記事下部の参考文献に記載
2. どんな開発に向いているのか
Darkは大きな目標として、「ソフトウェアの構築を100倍容易にすることでコーディングを民主化し、次の10億人がコーディングできるようにする」と挙げているが、初期段階では以下のような領域をターゲットにしています。
- モバイルアプリや、React, Vue, Anglarで記述された単一ページのWebアプリ等のクライアントアプリのバックエンド
- 既存のマイクロサービスベースのアーキテクチャで新しいサービスを構築すること
一方で、組み込みシステムや、定理証明、機械学習モデルなどは今後サポートする予定は無いとの事です。
3. 実際に動かしてみる
実際にDarkのチュートリアルを参考にして、「日付レポート」のAPIを実装していきます。
Darkにログインするとエディタが立ち上がります。画面は非常にシンプルで、サイドバー、ユーザ情報(右上)、ドキュメント(右下)のみである。基本的な操作は画面をクリックすると以下の図の様に機能の選択画面が表示されます。開発は、この画面をキャンバスの様に使用して都度、自分の使用したいものを選択・追加してく事で開発していきます。
3.1. Hello World
Hello Worldを作成してみます。手順は非常にシンプルです。
画面をクリックし、メニューが開かれた状態でhello
と入力すると、New HTTP handler named /hello
とメニューに表示されるので、それを選択すると/hello
ハンドラが作成されます。後は、リクエストメソッドと、valueを書くだけで完成です。作成したものは、右上の設定からOpen in new tab
で即時に確認する事ができます。
また、value
が未記入の場合、<Incomplete> Your code needs to return a value in the last expression
とエラーが表示されます。
※エンドポイントは、デフォルトではUSERNAME-gettingstarted.builtwithdark.com
となりますが、USERNAME-.builtwithdark.com
の2つ存在しました。エンドポイント変更はユーザ画像をクリックし、Account/Canvas
から切り換える事ができます。
【2020/03/22追記】
エンドポイントを書き換える事でプロジェクトを複数作成する事が可能で、新規プロジェクトを作成する際はエンドポイントを書き換えて更新すると良いです。
3.2. 演算
次に簡単な演算を行い、演算結果を渡してみます。
先程、同じ様にHTTPハンドラを作成し、リクエストメソッドをGET
、ルートを/add
に設定しました。
演算処理は、演算子を使用して簡単に記述する事も可能ですが、変数を宣言して行うことも可能です。
また、Darkではハンドラを作成すると、以下の様に各々の値を瞬時に確認する事ができます。
9(画像下部)
と出力されている場所は、このハンドラの戻り値です。5(画像左部)
はカーソルが置かれている位置の式の結果を表示しています。整数の場合では利便性を感じませんが、変数の場合は即座に結果を確認できます。
3.3. REPL
REPLを作成する際も、同様に選択画面からREPLを選択し作成していきます。今回は、敢えてエラーを起こしてその挙動も確認してみる事にします。
httpclient
と入力すると、HTTPClientのすべての標準ライブラリ関数、署名、およびdocstringが表示されます。今回は、HTTPClient::post
を使用しようと思うので、httpclientpost
まで打つと表示されました。Darkはオートコンプリートを行ってくれるので、正確なテキストを入力する事は不要です。
HTTPClient::post
を選択すると、受け取る為のパラメータ(URI
,Body
,Query
, Headers
)を自動的に作成され、それらを全て入力するとエディター内から式を実行できる実行ボタン(HTTPClient::post
の右側の灰色の三角形)が表示されます。
エンドポイントは今回、USERNAME.builtwithdark.com
を使用したので、以下の様に入力します。
https://USERNAME.builtwithdark.com/test
その他、パラメータを入力して実行しようとすると404
がレスポンスとして表示されます。これは、エンドポイント/test
がキャンバス上に存在しない為です。この結果は、サイドバーの404セクションからも確認できます。
一方、キャンバス上ではエラーはこの様に表示されます。
3.4. データストア
まず、先程のエンドポイントでのエラーを解決する為に、DarkではHTTPリクエストのトレースを使用してエンドポイントを構築します(トレース駆動開発)。404セクションにあるルート/test
の右側にある青色の+ボタンを押すと、POST
メソッドのルート/test
が作成されます。
作成されたものを確認してみると、Body
を含むREPLで設定したリクエスト情報が完全にトレースされている事が確認できます。
このリクエストを直接処理し、let data = request.body
を入力して取得した情報をレコードに保存します。ここでも、オートコンプリートを活用して記述していきます。
データストアは、HttpClientライブラリと同様に、空白に「DB」と入力すると、すべてのデータストア関数がプルアップされます。今回の場合では、db::set
を使用します。
データストアの作成は、サイドバーかキャンバス内をクリックして作成が可能です。今回は、Requests
と言うデータストアを作成しました。(小文字で入力して作成しても、最初の1文字目は大文字に変換してくれる様である)
Darkのすべてのデータストアはキー値ベースであり、キーをレコードの一意の識別子として使用します。今回の場合であると、data
、time
のキーを作成した場合は以下の様になります。
{
key1: {
data: {
test: "test2"
},
time:
},
key2: {
data: {
test: "test1"
},
time:
}
}
最初のパラメータは、挿入するレコードです。これは、日付と時刻のスキーマと一致します。Darkでは、DB::set
のすべてのフィールドを含める必要があり、上記のデータとDate::now
関数を挿入して時間を取得しています。2つ目はキーであり、各オブジェクトに一意のキーが必要です。この場合、db
と入力すると、組み込みのdb::GenerateKey
関数が取得できます。3つ目は、データストア名を指定します。データストアの名前はオートコンプリートで表示されます。
最後に、DB::set
を実行してみると以下の様にデータストアにレコードが挿入され、スキーマがロックされます。
3.5. CRON
今回は、dailyReport
と言うの名前のCRONを作成します。
日付レポートを作成する為には、現在の時間と比較する必要があります。まず、変数timeSeconds
を用意しDate::now
を設定します。次に、比較の為に秒単位の時間が必要の為、Date::toSeconds
も設定します。関数はパイプで繋げる事ができます。(|
と入力すると、|>
と表示される。)
リクエストの取得は、DB::getAll
を使用し、取得したいDBテーブル(Requests
)を指定します。リクエストはList型で取得されます。入力後に、実行してみると以下の様にリクエストが取得されている事が確認できます。
次に、List::filter
を使用してリクエストのフィルタリングを行います。List::filter
では、フィルタリングするリスト名と、匿名関数を設定します。
匿名関数では、リクエストが今日の情報であるかどうかを確認します。
変数requestSeconds
は、リクエスト内に内包されている時間date
です。リクエストの時間は秒に変換する必要がある為、CRONの最初の行と似ているが、val.time
でリクエストの時間を取得しパイプでDate::toSeconds
を繋げて変換しています。
変数difference
は、現在の時刻とリクエストの時間の差分を計算しています。 そして、差分の結果が24時間以内(86400秒)であるかどうかを判別します。
最後に、emit
を使用して、バックグラウンドワーカーにリクエストを送信します。emit
では、イベント名(todayRequests
)と、WORKER名(StoreReport
)を指定して送信を行います。
3.6. WORKER
CRONを実行すると、WORKERは存在していないので404セクションに表示されます。その為、先程と同じ様に404セクションからStoreResort
を選択すると、既に名前がついた状態で作成されます。作成されたWORKERにカーソルを合わせると、CRONによってトリガーされイベントが表示されます。
実際に、WORKERの機能を実装すると以下のようになります。
レポートでは、MM-DD-YYYY
の表記でデータを保存する為、現在時刻を取得し、それぞれを分割して変数humanDate
でフォーマット変換を行いました。
※+
はint型の場合でのみ使用できる様で、String型の場合は++
を使用する事で文字列を連結する事ができます。
変数data
では、リクエストに内包されているdata
のみを取得しています。List::map
を使用する事で、リスト内のオブジェクトのコレクションに対して操作する事ができます。
レポートの保存は、新たにDailyReport
と言うデータストアを作成しているが、外部APIを使用する事も可能です。
以上で、実装は終了です。ここまでの実装したものを並べると以下のようになります。
3.7. 動作検証
REPL内で記述した、BODY部分をtest 1
から、hello Dark!
に変更して実行してみます。
実行すると、/test
ハンドラでは新しいトレースドットが表示され、リクエストのBODYが、hello Dark!
になっている事が確認できます。
データストアも同じく、DBに追加されたレコードが表示されます。
CRONの方も確認してみると、DBのレコードが全て取得できている事が確認できていますが、時系列毎にソートして表示されてはいない為探すのに苦労しました。筆者が不必要に連打したのが原因でもありますが、レコードが増えていく事が想定されると目を通すのには可読性が悪く、少し労力が掛かるなと感じました。
WORKERも同じ事が言えると思います。しかし、Eventは実行された時系列毎に保存されており、前回との差分の確認や以前のデータの内容を確認する事ができます。
最後に、日付レポートのデータストアも確認すると、日付毎にレコードが登録されている事が確認できます。
また、新たにREPLを作成し日時レポートとその内部の項目数を取得してみました。実行してみると、DailyReport
から日付毎にレポートを取得する事ができます。試しに異なる日付のレコードも登録した所、そちらも同じく取得する事ができました。
ハンドラなどを削除すると、Deletedセクションが表示されます。Deleteセクションから削除されたハンドラやデータストアを見ることができ、復元すると即座にデプロイし直され元の状態に復元する事ができます。
4. 総評
初めてDarkを触り、直感的操作で開発を行う事ができました。確かに、初期段階ではDarkのツールセットについての学習コストは発生するものの、従来の開発言語を覚える程では現段階は無いと感じます。
また、コードを書くことと並行してトレーシングが行われ、Dark内で作成したものはオートセーブされる為、ウィンドウを閉じても再度立ち上げると以前の状態から再開する事ができるので逐一保存する面倒もありません。
デプロイレスと言う指向は、これまでいくつかのサービスで実装しようと試みて来ていましたが、Darkが初めての成功例ではないでしょうか。開発者は、アプリケーションのコードを書くだけで良く、書き終わったコードは既にホストされていると言うのは非常に有り難い事です。CircleCIを開発してきたPaul Bigger氏だからこそ、デプロイに深く精通し、その中に存在する課題を解決する策として見出せたのだと思います。
ベータ版ではあるが、既にある程度の開発も可能でReact SPAや、Slackbotの開発もできるようなので今後試しに実装しようと思います。
しかし、バグもまだ存在しているのでこれからの改善に大きく期待すると共に今後の開発に貢献していけたらと思います。
最後に、本記事を見てDarkを触れてみたいと感じた人が少しでも増えてくれれば幸いです。ベータ版は、Darkの公式サイトから登録が可能で招待されるまでに時間は掛かります(筆者はベータ版開始から大体2,3ヶ月待った)が是非この機会に登録してみて下さい。
5. 謝辞
本記事を作成するに至り、快く承諾してくれたCEOのEllen Chisaに深く感謝いたします。