はじめに
こんにちはーFlasherのみなさん。
すっかりRuby記事ばっかりなのに、いまだにブログ訪問者の大半はFlasherらしいこのブログ。
久しぶりにFLASHerのための記事を書けそうです。
今日とりあげるのはSinatraというRubyで作られた超シンプルなフレームワークです。
- require 'rubygems'
- require 'sinatra'
- get '/hi' do
- "Hello World!"
- end
このたった5行で、http://localhost:4567/hi にアクセスすると「Hello World!」というテキストを返すAPIサーバがローカルPC上に完成するんだ。
Rubyがわからなくたって、どんなプログラムなのか一目瞭然だ。シンプルだと思わないかい?
今回はこのシンプルなSinatraを使って、あなたのFlash案件に使える、より本番に近いモックAPIサーバを作ろうというお話です。
この記事の対象者
- サーバ連携なFlash案件が多いFlash開発者
- Macユーザー(Windowsの人もインストール編以外は共通だと思う)
- ターミナル.appが少しは触れる人(達人じゃなくてよい)
今回のシチュエーション
FlashでToDo管理アプリを作ることになった。 まずはToDoの一覧をサーバからXMLで取得して、それが表示できるようにしたい。
APIのURLと、どんなXMLが返ってくるかは決まっているんだけど、肝心なサーバ側は完成していないどころかリリース前日には出来上がるスケジュールらしい。 こうなったら自分でダミーAPIを用意しながら開発するしかない。
ToDo一覧を取得するAPIと返ってくるXMLのサンプル
http://example.jp/api/todolist
- <?xml version="1.0" encoding="UTF-8"?>
- <todos>
- <todo id=‘1’>
- <title>牛乳を買って帰る</title>
- </todo>
- <todo id=‘2’>
- <title>企画書を提出する</title>
- </todo>
- </todos>
効率よく開発を進めるためのFlashの設計
さて、上記のようなシチュエーションの場合、ローカルにダミーXMLを配置して、それを読み込むというのが一番てっとり早い開発手法なんだと思う。 しかしAPIの種類が100種類とか膨大だったり、同じAPIでもパラメーターで返却のバリエーションが変わるとか想定すると、本番により近いAPIモックを用意できるのがベストだ。
例えば本番APIとドメイン以外まったくURLが同じという構成があったら、Flashの設計も随分綺麗になると思うよ。
- import flash.events.*;
- import flash.net.*;
- // 実行環境をSWF起動時に設定する
- var environment:String = 'development';
- // 設定
- var setting:Object = {
- production: { // 本番用
- host: 'http://example.jp'
- },
- development: { // 開発用
- host: 'http://localhost:4567'
- }
- };
- // ローダー
- var request:URLRequest = new URLRequest(setting[environment].host.concat('/api/todolist'));
- var loader:URLLoader = new URLLoader();
- loader.addEventListener(Event.COMPLETE, function(e:Event) {
- trace(URLLoader(e.target).data);
- });
- loader.load(request);
上のコードでは、「environment」変数の中身がdevelopmentなら開発環境用のAPIを、productionなら本番環境用のAPIをリクエストする。
インストール編
ここからはSinatraをインストールする話
Sinatraでモックサーバを作るには最低でも以下のようなものが要求されるよ、がんばれ!
- ターミナル.appの操作
- ruby
- rubygems
- sinatra
まずはターミナル.appを起動しよう。Macの「/アプリケーション/ユーティリティ/」に入っている。これを機会にターミナルをDockに入れておいたら周りの同僚に一目おかれるかもね。
起動したらRubyが入っているか確認だ。MacOS10.4くらいからRubyは最初から入っているはず。最新の10.6ならRubyのバージョンは1.8.7のはずだ。
- % ruby -v
- ruby 1.8.7 (2008-08-11 patchlevel 72) [universal-darwin10.0]
次にrubygemsのバージョン確認。rubygemsはrubyのサードアプリをインストールしたりするための管理ツールだよ。 今回のSinatraもそうだし、有名なRuby on Railsもrubygemsでインストールできるんだ。
- % gem -v
- 1.3.5
ひょっとしたらバージョンは1.3.5より低いかも。そのままでも大丈夫だと思うけどアップグレードするなら。
- % sudo gem update —system
でアップグレードしよう。
Sinatraのインストール
さて、RubyGemでお目当てのSinatraをインストールする。ついでに他にも使えそうなライブラリをいれておくよ。
- sudo gem install sinatra haml rack shotgun
パスワードを要求されるので、自分のアカウントのパスワードを入力しよう。するとインストールが始まる。
お疲れ様でした!あとはダミーサーバを書くだけだ。
さぁ、SinatraでダミーAPIを書くんだ!
ここまで準備ができたら、Flashプロジェクトの中にでもsinatra用のディレクトリ「mock」を作る。全体の構成はこんな感じにしたよ。
mockディレクトリの中にapp.rbというテキストファイルを作成して、エディタで以下のように書く。
- require 'rubygems'
- require 'sinatra'
- get '/api/todolist' do
- 'Hello World!'
- end
そして、ターミナルでプロジェクトのmockディレクトリまで移動してサーバを起動しよう。 え?ターミナルでmockディレクトリまで移動ができない? デスクトップにmytodosプロジェクトフォルダがあるなら
- % cd ~/Desktop/mytodos/mock
と入力してエンターだ。
それでもわからなかったら、「cd 」とだけ書いて、移動したいフォルダをターミナルへドラッグドロップでもオッケー。
そしてサーバ起動だ。
- % ruby app.rb
こんな感じになってるかな?
なっていれば、君による君だけのAPIサーバが起動した。おめでとう! そうそう、サーバを止めたい時はCTRL+Cを押すんだよ。
ブラウザで http://localhost:4567/api/todolistアクセスしてみよう。
すごい!完璧だ!サーバサイドエンジニアになれるんじゃないか?!
モックAPIを作る
僕らの目的は「Hello World」を表示することじゃない。XMLを返すサーバを作ることだから先を急ぐよ。
mock/app.rbをちょっと変更してきちんとXMLを返すようにしてみるよ
- require 'rubygems'
- require 'sinatra'
- get '/api/todolist' do
- content_type 'xml'
- erb :api_todolist
- end
そして、mock/views/api_todolist.erb というファイルを作成して
- <?xml version="1.0" encoding="UTF-8"?>
- <todos>
- <todo id='1'>
- <title>牛乳を買って帰る</title>
- </todo>
- <todo id='2'>
- <title>企画書を提出する</title>
- </todo>
- </todos>
としよう。
ブラウザでアクセスすれば、今度はXMLが返ってくるようになったはずだ。
簡単に説明すると、「content_type ‘xml’」でXMLとしてレスポンスを返すように定義して、 「erb :api_todolist」で views/api_todolist.erbというテンプレートファイルを出力してね。
ということになる。ERBというのはRubyでスタンダードなテンプレートシステムだ。
参考:http://www.druby.org/ilikeruby/erb.html
もうちょっと高度なことをする
これじゃローカルにXMLを置くのと変わらないよドラえもーん、と嘆いている、そこののび太くん。 ERBを使えば繰り返しが可能なので、例えば999件のXMLを返したい時はこうだ。
mock/views/api_todolist を修正
- <?xml version="1.0" encoding="UTF-8"?>
- <todos>
- <% 999.times do |id| %>
- <todo id='<%= id %>'>
- <title>牛乳を買って帰る <%= id %></title>
- </todo>
- <% end %>
- </todos>
数値.times do ~ end で数値分繰り返し処理されるのはRuby独特の書き方だ。
さらに高度なことをする
単純な繰り返しじゃいやだ!自分でレコードを作りたい!でもデータベースは嫌だ! OK。ならこうだ。
mock/app.rb修正
- require 'rubygems'
- require 'sinatra'
- get '/api/todolist' do
- # TODOの配列を作る %w はRubyの配列式
- @todos = %w{
- コンビニに寄る
- ジャンプを立ち読みする
- 牛乳をレジへ持っていく
- 178円払う
- 店員さんにありがとうと言う
- 牛乳を買って帰る
- 牛乳を冷蔵庫へしまう
- }
- content_type 'xml'
- erb :api_todolist
- end
mock/views/api_todolist.erb修正
- <?xml version="1.0" encoding="UTF-8"?>
- <todos>
- <% @todos.each_with_index do |todo, id| %>
- <todo id='<%= id %>'>
- <title><%= todo %></title>
- </todo>
- <% end %>
- </todos>
app.rbで設定した@todosをテンプレートからアクセスしている。
@todos.each_with_index do |element, index| ~ end という形もRubyでは日常茶飯事に使われる配列の繰り返し方。
さいごに
ざっとFLASHerがSinatraを使ってモックサーバを用意する方法を書いてみた。
Sinatra側のコードは書き換える度にサーバを再起動する必要があるから注意してね。 それがめんどくさい場合はshotgunコマンドを使うと、再起動の心配は必要無くなる。
- % shotgun app.rb
駆け足だったので、もっと具体的なことをしたいとか、これはどーやって実現するんだ?という質問があったら、コメントなりメールなり@func09なりへどうぞ。
それから、モックサーバを作るためにRubyにハマりすぎると、僕みたいにFlasherを引退してまでRubyを書くことになっちゃうからほどほどにね。
enjoy flash and ruby!
参考URL: AS3でちょっとしたサーバサイドのプログラムが必要になる時に毎回書くのが面倒なので、適当に sinatra で書いた





2月 17th, 2010 at 1:31 PM #[sinatra for flasher] 大量のダミーデータを返すAPIを作る - func09
[...] FLASHer のためのSinatra入門 [導入編] [...]
2月 18th, 2010 at 2:05 PM #KRAY » Blog Archive » FLASHerのためのSinatra入門
[...] FLASHer のためのSinatra入門 [導入編] http://www.func09.com/wordpress/archives/764 [...]