ぽっちぽちにしてやんよ

技術ネタとかアプリに関する話とか

[Synth] Synthを試してみた

synth

tl;dr

  • SynthっていうAPI-firstなWebフレームワークがある
  • Turoialを回してみた
  • RESTfullなAPIとディレクトリ構造,exportsのI/Fを合わせる規約で見通し良い
  • プリロードの仕組みで初めからレンダリングできるよ!
  • まだ超beta.

前説

Synth はNode.js製のAPI-firstなWebフレームワーク. back/resourcesディレクトリに.js/.coffeeを配置して,exports.get = ...とかexports.getIndex =とかexports.<method><optional: ActionName>な形で書いておくと,myapp/back/resources/memoesGET /api/memoesとかに答えてくれる.

ひとまず,Tutorial を回して,Angular以外を使う道を探ろう.

あと超betaらしいから地雷踏む勇気が無い人はProductionに使えない.

インストールとセットアップ

1
2
3
$ npm install -g synth
$ $ synth new my_app
Successfully created a new synth app in my_app

ディレクトリ構造

1
2
3
4
5
6
7
$ cd my_app
$ ls
back       front      synth.json
$ ls front/
bower.json css        html       images     index.jade js         misc
$ ls back/
back-app.js       generateTweets.js package.json      resources

こんな感じになっている.

frontはクライアントサイドのやつが詰まってる. backはサーバサイドのやつが詰まってる.

synth newはTwitterクローンが生成されるみたい.

パッケージインストール

1
2
$ synth install -b
$ synth install -f

でそれぞれfrontのbower installとbackのnpm installが走る.

起動

1
2
$ synth server -p 5000
synth (in development mode) is now listening on port 5000

http://localhost:5000 にアクセスすると表示される. Synth Appとか出て何も表示されない.Tweetを生成してあげないといけないらしい.

1
$ node back/generateTweets.js

そしてリロードするとTweetが出た.

処理の追加

このままだとただのTweet表示君なので,Tweetする機能を付ける.

backend側

back/resources/tweets/.jsファイルを置いてexports.post = ...を書けばいい.

1
$ touch back/resources/tweets/createTweets.js
1
2
3
4
5
6
7
8
9
10
$ cat back/resources/tweets/createTweets.js 
  exports.post = function(req, res) {
    if (!req.body.content) {
      throw 422;
    }
    return req.db.collection('tweets').insert({
      content: req.body.content.slice(0, 140),
      created_at: new Date
    });
  };

ちなみにback/resources/tweets/createTweets.coffeeを置いたら読んでくれなかった. きっと全部.coffeeにしないとダメ.とりあえず先に行く.

frontend側

/front/js/controllers/tweets.js に処理を追記.

1
2
3
4
5
6
7
8
9
10
11
$ cat front/js/controllers/tweets.js 
angular.module('my_app')
.controller('tweetsController', function ($scope, $http, data) {
  $scope.tweets = data.tweets;
  $scope.publish = function () {
    $http.post('/api/tweets', { content: $scope.newTweet })
    .success(function (tweet) {
      $scope.tweets.unshift(tweet);
    });
    $scope.newTweet = '';
  };

こうする.

HTMLの方もボタンを付けたり,textareaを付けたりしないといけない.

1
2
3
4
5
6
7
$ cat front/html/tweets/getIndex.jade
textarea(ng-model="newTweet")
button(ng-click="publish()", ng-disabled="newTweet.length == 0") Publish
ul.tweet-timeline
  li.tweet(ng-repeat="tweet in tweets")
    .content 
    .date 

こうする.

確認

もう一度 http://localhost:5000 にアクセスすれば,textareaとpublishボタンがある. hogeとか書いてpublishすればめでたくTweetが追加される.

Preload

Synthの強みとしてプリロードの機能があるらしい. backend側でpromiseで返せば,front側で初めからデータを持った状態でレンダリング出来る. rendr みたいなものか.

front/index.jadeを確認してみると,

1
2
3
// Preloaded Data
script.
  var preloadedData = !{data};

とか

1
2
3
if preloadHTML
  script(type="text/ng-template", id="#{preloadHTMLPath}")
    != preloadHTML

ここらへんがプリロードの鍵らしい.

ソース を覗いてみると,

1
2
3
4
5
6
7
8
9
10
11
var renderData = {
  appName: req.appName || 'Synth App',
  jsFiles: assets.jsFiles,
  cssFiles: assets.cssFiles,
  data: prepareData(preload.data),
  preloadHTML: preload.html,
  preloadHTMLPath: htmlPath
};
for (var key in res.renderData) {
  renderData[key] = res.renderData[key];
}

がres.renderに渡ってるっぽい.

1
2
3
4
5
exports.get = function(req, res) {
  :
  res.renderData[hoge] = 'fuga'
  :
}

とかbackend側でやってあげれば,front側にデータを渡せそう.

Angular以外で使ってみる

時間が来たから,また夜にでも続き書く.

Comments