東京Node学園 14時限目で「Synth」について話してきました

昨夜、渋谷ヒカリエで行われた東京Node学園 14時限目で、トップバッターとして発表してきました。

発表の様子

発表内容は、「Synth」というWebアプリケーションフレームワークについてです。

Tokyo Otaku Modeでは、バックエンドとしてNode.jsとMongoDBを使っていてExpressで運用していますが、色んなフレームワークも触っていてSynthもそのうちの一つです。

SynthはInfoQの「APIファーストのWebフレームワークSynthを巡るコミュニティの困惑」という日本語版記事が出て初めて知った人が多いと思います。
記事にもあるとおり、JSONやテンプレートHTMLを返すAPIとそれを使ってクライアント側でアプリケーションを構築するという形に特化したAPIファーストのWebアプリケーションフレームワークです。

ちょうど上記の記事が出た頃、天下一クライアントサイドJS MV*フレームワーク武道会の募集などがあり、API構築が簡単そうなバックエンドとしてSynthを触ってみたのがはじめでした。

そのあと触ってみた記事を個人のブログに書いていたりしたところ、東京Node学園主催の@yosuke_furukawaから声をかけて頂いて発表することになりました。

Synth自体はまだベータの段階で、どんどんコントリビュート出来るので、気になることがあったらプルリクエストを出しましょう
僕もプルリクエストを出して、すぐに取り込まれました。

スライドは全て英語で書いてます、日本語での詳細解説を以下に書きました

Synthの4つのユニークな特徴

発表ではSynthの持つ4つのユニークな特徴を軸にSynthの紹介を行いました。

4つのユニークな特徴とは、

  1. APIファースト
  2. ディレクトリ構造がそのままAPIのURL階層とマッピングされる
  3. 初期データ・初期テンプレートのプリローディング
  4. ハンドラをPromiseで返すことを要求する

です。

1. APIファースト

Synthは上でも少し触れましたが、2つの要素で構成されています。

  1. JSONやテンプレートHTMLを返すAPIを司るバックエンド
  2. クライアントサイドMV*で作られるフロントエンド

expressなどでもres.jsonを使えばJSONを返すエンドポイントは構築できるのですが、Synthはバックエンドサーバーとしては/api/tweetのようなエンドポイントを備えJSONやテンプレートHTMLを返すAPIサーバとして特化しています。

2. ディレクトリ構造がそのままAPIのURL階層とマッピングされる

Synthはback/resources/以下にディレクトリを切り、その中にjs/coffeeファイルを入れることでAPIエンドポイントを増やすことが出来ます。
/api/memosみたいなAPIを増やしたければ、

  1. back/resources/memos/を作る
  2. back/resources/memos/getMemos.jsのようなファイルを作る

ということだけで、すぐにAPIエンドポイントを増やすことが出来ます。

3. 初期データ・初期テンプレートのプリローディング

ここまでの話で、SynthのバックエンドはクライアントサイドMV*から使われることを前提に作られているのに気づかれると思います。

それもそのはずで、SynthはクライアントサイドMV*の初期アクセス時に画面は描画されているにも関わらず、ローディングインジケータが回ってコンテンツが表示さていないという良くある挙動を解決するためにアプローチされたフレームワークなのです。

クライアントサイドMV*を使ったアプリケーションでは、AjaxでJSONのデータを取得してModelを構築しViewに描画するという流れを取っているため、どうしてもHTTP通信が2回走っていまいます。そのため初回描画時にコンテンツが描画されていないという現象が起こります。

Synthでは、はじめの画面を描画する際にクライアントサイドMV*で言うModelに必要なデータと、Viewに必要なテンプレートを含めて返してしまうというアプローチをしています。

コード的にはこのような形になっています。

1
2
3
4
5
6
7
8
9
10
11
(index.jade - 途中略)
script.
var preloadedData = !{data};
body
h1= appName

div(ng-view)

if preloadHTML
script(type="text/ng-template")
!= preloadHTML

これによってpreloadedDataにはModelを構成するのに必要なデータが入り、初回にAjax通信を必要とせずコンテンツを描画することができます。

4. ハンドラをPromiseで返すことを要求する

プリローティングを実現するのに、SynthはPromiseを使っています。

以下に挙げるのはSynthのサンプルコード内にある/api/tweetsを返すリクエストハンドラです。

1
2
3
4
5
6
7
8
9
10
exports.getIndex = function (db) {
return db.collection('tweets').find()
.sort({ created_at: -1 })
.limit(30)
.toArray().then(function (tweets) {
return {
tweets: tweets
};
});
};

dbpromised-mongoというmongodbへの検索をPromiseで返してくれるライブラリのインスタンスです。

.toArray().then(function (tweets) {というところに注目して頂きたいのですが、Promiseを返しています。

Synthは内部的には、bluebirdPromise.propsでリクエストハンドラで返すPromiseのresolveを待って、index.jadeにデータを受け渡しています。

まとめ

このように、Synthは他のWebアプリケーションフレームワークとはちょっと違ったユニークなアプローチを取って、問題の解決を図ったフレームワークです。

Synthはまだまだベータ版で、APIや挙動等変化が大きいため実プロダクトに適用するのは難しいかもしれませんが、アプローチとしては面白い(作者はクレイジー上等と言っています)ので触ってみるといいかもしれません。

Tokyo Otaku Modeでは、ベータ版のフレームワークでもガンガン触ってみようと考える好奇心あふれるエンジニアを募集しています!
こちらからご応募ください!
(「ブログを見た」とひと言いただければ、僕らエンジニアが喜びます)