Help us understand the problem. What is going on with this article?

新たな開発プラットフォーム "Dark/Darklang" を実際に触ってみて

はじめに

先日、私が以前に申請していた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にログインするとエディタが立ち上がる。画面は非常にシンプルで、サイドバー、ユーザ情報(右上)、ドキュメント(右下)のみである。基本的な操作は画面をクリックすると以下の図の様に機能の選択画面が表示される。開発は、この画面をキャンバスの様に使用して都度、自分の使用したいものを選択・追加してく事で開発していく。

Screen Shot 2020-03-19 at 4.09.18.png

3.1. Hello World

Hello Worldを作成してみる。手順は非常にシンプルである。

ezgif.com-video-to-gif.gif

画面をクリックし、メニューが開かれた状態で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に設定した。

演算処理は、演算子を使用して簡単に記述する事も可能だが、変数を宣言して行うことも可能である。

ezgif.com-video-to-gif.gif

また、Darkではハンドラを作成すると、以下の様に各々の値を瞬時に確認する事ができる。

Screen Shot 2020-03-20 at 15.20.26.png

9(画像下部)と出力されている場所は、このハンドラの戻り値である。5(画像左部)はカーソルが置かれている位置の式の結果を表示している。整数の場合では利便性を感じないが、変数の場合は即座に結果を確認できる。

3.3. REPL

REPLを作成する際も、同様に選択画面からREPLを選択し作成していく。今回は、敢えてエラーを起こしてその挙動も確認してみる事にする。

httpclientと入力すると、HTTPClientのすべての標準ライブラリ関数、署名、およびdocstringが表示される。今回は、HTTPClient::postを使用しようと思うので、httpclientpostまで打つと表示された。Darkはオートコンプリートを行ってくれるので、正確なテキストを入力する必要は無い。

HTTPClient::postを選択すると、受け取る為のパラメータ(URI,Body,Query, Headers)を自動的に作成され、それらを全て入力するとエディター内から式を実行できる実行ボタン(HTTPClient::postの右側の灰色の三角形)が表示される。

ezgif.com-video-to-gif (1).gif

エンドポイントは今回、USERNAME.builtwithdark.comを使用したので、以下の様に入力する。

https://USERNAME.builtwithdark.com/test

その他、パラメータを入力して実行しようとすると404がレスポンスとして表示される。これは、エンドポイント/testがキャンバス上に存在しない為である。この結果は、サイドバーの404セクションからも確認できる。

Screen Shot 2020-03-20 at 16.47.00.png

一方、キャンバス上ではエラーはこの様に表示される。

Screen Shot 2020-03-20 at 16.47.34.png

3.4. データストア

まず、先程のエンドポイントでのエラーを解決する為に、DarkではHTTPリクエストのトレースを使用してエンドポイントを構築する(トレース駆動開発)。404セクションにあるルート/testの右側にある青色の+ボタンを押すと、POSTメソッドのルート/testが作成される。

ezgif.com-video-to-gif (2).gif

作成されたものを確認してみると、Bodyを含むREPLで設定したリクエスト情報が完全にトレースされている事が確認できる。

Screen Shot 2020-03-20 at 17.09.33.png

このリクエストを直接処理し、let data = request.bodyを入力して取得した情報をレコードに保存する、ここでも、オートコンプリートを活用して記述していく。

ezgif.com-video-to-gif (3).gif

データストアは、HttpClientライブラリと同様に、空白に「DB」と入力すると、すべてのデータストア関数がプルアップされる。今回の場合では、db::setを使用する。

データストアの作成は、サイドバーかキャンバス内をクリックして作成が可能である。今回は、Requestsと言うデータストアを作成した。(小文字で入力して作成しても、最初の1文字目は大文字に変換してくれる様である)

Darkのすべてのデータストアはキー値ベースであり、キーをレコードの一意の識別子として使用する。今回の場合であると、datatimeのキーを作成した場合は以下の様になる。

{
  key1: {
          data: {
                  test: "test2"
                },
          time: 
        },
  key2: {
          data: {
                  test: "test1"
                },
          time: 
        }
}

最初のパラメータは、挿入するレコードである。これは、日付と時刻のスキーマと一致する。Darkでは、DB::setのすべてのフィールドを含める必要がある。上記のデータとDate::now関数を挿入して時間を取得している。2つ目はキーであり、各オブジェクトに一意のキーが必要である。この場合、dbと入力すると、組み込みのdb::GenerateKey関数が取得できる。3つ目は、データストア名を指定する。データストアの名前はオートコンプリートで表示される。

最後に、DB::setを実行してみると以下の様にデータストアにレコードが挿入され、スキーマがロックされる。

Screen Shot 2020-03-20 at 17.59.47.png

3.5. CRON

今回は、dailyReportと言うの名前のCRONを作成する。

日付レポートを作成する為には、現在の時間と比較する必要がある。まず、変数timeSecondsを用意しDate::nowを設定する。次に、比較の為に秒単位の時間が必要の為、Date::toSecondsも設定する。関数はパイプで繋げる事ができる。(|と入力すると、|>と表示される。)

リクエストの取得は、DB::getAllを使用し、取得したいDBテーブル(Requests)を指定する。リクエストはList型で取得される。入力後に、実行してみると以下の様にリクエストが取得されている事が確認できる。

Screen Shot 2020-03-21 at 13.41.48.png

次に、List::filterを使用してリクエストのフィルタリングを行う。List::filterでは、フィルタリングするリスト名と、匿名関数を設定する。

Screen Shot 2020-03-21 at 20.44.58.png

匿名関数では、リクエストが今日の情報であるかどうかを確認する。

変数requestSecondsは、リクエスト内に内包されている時間dateである。リクエストの時間は秒に変換する必要がある為、CRONの最初の行と似ているが、val.timeでリクエストの時間を取得しパイプでDate::toSecondsを繋げて変換している。

変数differenceは、現在の時刻とリクエストの時間の差分を計算している。 そして、差分の結果が24時間以内(86400秒)であるかどうかを判別する。

最後に、emitを使用して、バックグラウンドワーカーにリクエストを送信している。emitでは、イベント名(todayRequests)と、WORKER名(StoreReport)を指定して送信を行う。では、次にWORKERの作成について説明する。

3.6. WORKER

CRONを実行すると、WORKERは存在していないので404セクションに表示される。その為、先程と同じ様に404セクションからStoreResortを選択すると、既に名前がついた状態で作成される。作成されたWORKERにカーソルを合わせると、CRONによってトリガーされイベントが表示される。

Screen Shot 2020-03-21 at 17.08.24.png

実際に、WORKERの機能を実装すると以下のようになる。

Screen Shot 2020-03-21 at 17.44.18.png

レポートでは、MM-DD-YYYYの表記でデータを保存する為、現在時刻を取得し、それぞれを分割して変数humanDateでフォーマット変換を行った。

+はint型の場合でのみ使用できる様で、String型の場合は++を使用する事で文字列を連結する事ができる。

変数dataでは、リクエストに内包されているdataのみを取得している。List::mapを使用する事で、リスト内のオブジェクトのコレクションに対して操作する事ができる。

レポートの保存は、新たにDailyReportと言うデータストアを作成しているが、外部APIを使用する事も可能である。

以上で、実装は終了である。ここまでの実装したものを並べると以下のようになる。

Screen Shot 2020-03-21 at 18.17.39.png

3.7. 動作検証

REPL内で記述した、BODY部分をtest 1から、hello Dark!に変更して実行してみる。

Screen Shot 2020-03-21 at 18.43.25.png

実行すると、/testハンドラでは新しいトレースドットが表示され、リクエストのBODYが、hello Dark!になっている事が確認できる。

Screen Shot 2020-03-21 at 18.49.31.png

データストアも同じく、DBに追加されたレコードが表示される。

Screen Shot 2020-03-21 at 18.53.09.png

CRONの方も確認してみると、DBのレコードが全て取得できている事が確認できているが、時系列毎にソートして表示されてはいない為探すのに苦労した。筆者が不必要に連打したのが原因でもあるが、レコードが増えていく事が想定されると目を通すのには可読性が悪く、少し労力が掛かるなと感じた。

Screen Shot 2020-03-21 at 19.02.00.png

WORKERも同じ事が言える。しかし、Eventは実行された時系列毎に保存されており、前回との差分の確認や以前のデータの内容を確認する事ができる。

Screen Shot 2020-03-21 at 19.07.59.png

最後に、日付レポートのデータストアも確認すると、日付毎にレコードが登録されている事が確認できる。

Screen Shot 2020-03-21 at 23.53.42.png

また、新たにREPLを作成し日時レポートとその内部の項目数を取得してみた。実行してみると、DailyReport
から日付毎にレポートを取得する事ができた。試しに異なる日付のレコードも登録した所、そちらも同じく取得する事ができた。

Screen Shot 2020-03-21 at 20.48.28.png

ハンドラなどを削除すると、Deletedセクションが表示される。Deleteセクションから削除されたハンドラやデータストアを見ることができ、復元すると即座にデプロイし直され元の状態に復元する事ができる。

ezgif.com-video-to-gif (1).gif

4. 総評

初めてDarkを触り、直感的操作で開発を行う事ができた。確かに、初期段階ではDarkのツールセットについての学習コストは発生するものの、従来の開発言語を覚える程では現段階は無いと感じる。

また、コードを書くことと並行してトレーシングが行われ、Dark内で作成したものはオートセーブされる為、ウィンドウを閉じても再度立ち上げると以前の状態から再開する事ができるので逐一保存する面倒もない。

デプロイレスと言う指向は、これまでいくつかのサービスで実装しようと試みて来たが、Darkが初めての成功例ではないだろうか。開発者は、アプリケーションのコードを書くだけで良く、書き終わったコードは既にホストされていると言うのは非常に有り難い事である。CircleCIを開発してきたPaul Bigger氏だからこそ、デプロイに深く精通し、その中に存在する課題を解決する策として見出せたのだと思う。

ベータ版ではあるが、既にある程度の開発も可能でReact SPAや、Slackbotの開発もできるようなので今後試しに実装してみる。

しかし、バグもまだ存在しているのでこれからの改善に大きく期待すると共に今後の開発に貢献していけたらと思う。

最後に、本記事を見てDarkを触れてみたいと感じた人が少しでも増えてくれれば幸いである。ベータ版は、Darkの公式サイトから登録が可能で招待されるまでに時間は掛かる(筆者はベータ版開始から大体2,3ヶ月待った)が是非この機会に登録して欲しい。

5. 謝辞

本記事を作成するに至り、快く承諾してくれたCEOのEllen Chisaに深く感謝する。

参考文献

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした