WAF の設計方法 – 冬通りに消え行く制服ガールは、夢物語にリアルを求めない。 – subtech
Web + App は大人気 Sinatora もそういう考えっぽいですが (誤解しているかもしれません)、Web というのが App へのインターフェイスの一つにすぎず、例えば CLI + App という組み合せもあるし、Desktop GUI + App という組み合せも考慮されています。ロジックのテストはしやすそうでいいですね。でも、もっと富豪的でもおこられないんじゃないかなぁとも思うのです。
WebApp の場合、Web (というよりHTTP) を唯一のインターフェイスとして提供し、例えばCLIだろうがGUIだろうが、HTTP を仲介するようにします。HTTP + App, CLI→ HTTP + App, GUI→ HTTP + App。これは例えばGAEだと、そもそもこういう方法をとることしかできません。Cron もHTTPで特定のURLが叩かれるだけです。ユーザ向けAPIみたいなのがだいたいのサービスでありますが、それをアプリケーションのオーナーまで権限を拡張しているような感じです。
読んでいてすごく面白かったです。
僕も先日、CLIアプリのWebインターフェースを作っている途中で、「ん?」と引っかかっていた部分があったんですが、id:cho45さんのエントリーを見て氷解しました。
require 'sinatra/base'
# Fooがアプリ名だと思ってください
class Foo::Web < Sinatra::Base
get '/run' do
# code...
end
end
rack(map)もsinatraもこう書くのでrouterとAppの結合が強く、Appを別クラスにして委譲したくなる。
require 'sinatra/base'
# Fooがアプリ名だと思ってください
class Foo::Web < Sinatra::Base
get '/run' do
Foo::App.run
end
end
class Foo:App
def self.run
# code...
end
end
こうすればCLIも同じ様に書けて便利だ!
require 'sinatra/base'
# Fooがアプリ名だと思ってください
class Foo::Web < Sinatra::Base
get '/run' do
Foo::App.run
end
end
class Foo::CLI
def run
Foo::App.run
end
end
class Foo::App
def self.run
# code...
end
end
うんうん。で、gemでのfoo/bin/foo(コマンド)を作ろうとして、「ん?」となった。
foo/bin/foo:
#!/usr/bin/env ruby
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
require 'foo'
Foo::......
あれ?
httpdを立ち上げるコマンドにすればいいのか、CLIを呼び出すコマンドにすればいいのかどっちだろう・・・?
food(foo daemon)とfooの両方をbinに用意する?
んーなんだかなー・・・。
となっていたのです。
「Webだけでいいじゃん」
というのは目から鱗。Webからのテストを充実させれば問題無し!
ただ、「微妙なところ」として上げられている中でも「テストが遅くなりがち」というところは凄く気になっています。
mockもやりすぎると品質が落ちるし、かといって、継続的インテグレーションサーバーを使ってテストしてもらうのは面倒だし、品質の高いままサクサクできる方法がないかと悩んでいます。