Genel Özellikler • RACK Application * • Küçük ölçekli web uygulamaları • Saniyede 2000 request kapasite • Hız ve düşük hafıza kullanımı • Kolay kurulum ve deployment • “1 file app” * RACK : Ruby ve Ruby Framework’leri için Web Sunucusu Blake Mizerany
Kullanım Alanları • Hızlıca Prototip hazırlamak • API sunmak / yapmak • Herhangi bir ilave framework kullanmadan Web Uygulaması yapmak • Apache+PHP’nin Ruby yansıması
Yardımcı Araçlar $ gem install shotgun thin $ shotgun server.rb == Shotgun/Thin on http://127.0.0.1:9393/ >> Thin web server (v1.5.0 codename Knife) >> Maximum connections set to 1024 >> Listening on 127.0.0.1:9393, CTRL+C to stop • shotgun • thin
Yakalayıcılar (Handlers) get '/merhaba/:user_name' do "Merhaba #{params[:user_name]}!" end get '/merhaba/*/numaran/*' do "#{params[:splat][0]}, #{params[:splat][1]}" end http://127.0.0.1:9393/merhaba/vigo/numaran/11 http://127.0.0.1:9393/merhaba/jspyconf
Params, Splat ve RegExp Kullanımı get '/indir/*.*' do |file, ext| "Dosya: #{file}, Tipi: #{ext}" end http://127.0.0.1:9393/indir/resim.jpg get %r{/kullanici/([\w]+)/?(\d+)?} do "Yakalananlar: #{params[:captures]}" end http://127.0.0.1:9393/kullanici/vigo http://127.0.0.1:9393/kullanici/vigo/1 get '/kazanan/:user/?:id?' do "Kazanan #{params[:user]}, id var mı? #{!params[:id].nil?}" end http://127.0.0.1:9393/kazanan/vigo http://127.0.0.1:9393/kazanan/vigo/1
Duruma Bağlı Yakalama (Conditions) :agent # AppleWebKit/536.28.10 # Sadece AppleWebKit tarayıcıları için get '/ajan', :agent => /AppleWebKit\/(\d+)/ do mversion = @params[:agent].first "AppleWebKit major sürümü: #{mversion}" end get '/ajan' do "Tüm tarayıcılar için..." end :host_name # http://localhost:9393/admin yakalar # http://127.0.0.1:9393/admin çalışmaz get '/admin', :host_name => /^local/ do "Sadece adminler girebilir!" end :provides get '/test_provide', :provides => :json do pass unless request.accept? 'application/json' { :username => 'vigo', :email => '[email protected]' }.to_json end
Kendi Durumumuz Oluşturalım set(:ihtimal) { |value| condition { rand <= value } } get '/piyango', :ihtimal => 0.1 do "Tebrikler kazandınız!" end get '/piyango' do "Kaybettiniz ):" end set(:test_auth) do |*roles| condition do unless roles.any? {|role| current_test_user.in_role? role } redirect "/sistem/giris", 303 end end end get "/sistem/giris/?" do "Bu sayfaları görüntülemek için sisteme giriş yapmanız gerekiyor!" end get "/sistem/profil/?", :test_auth => [:user, :guest] do "Profil bilgileri" end get "/sistem/admin/?", :test_auth => :admin do "Sadece admin olanlar görebiliyor" end
Post İşlemi # application.rb get '/post/test/?' do erb :post_form, :layout => :genel end post '/post/test/?' do @username = params[:username] erb :post_form, :layout => :genel end
Kullanıcı adı girin
<% if @username %> Göndermiş olduğunuz kullanıcı adı: <%= h @username %> <% end %>
Şablonlar (Templates) Sass ve Markdown get '/sass/*.sass' do content_type 'text/css', :charset => 'utf-8' sass params[:splat].first.to_sym, :style => :expanded, :views => "#{settings.root}/sass" end # sass/*.sass yakalamak için get '/sayfa/ornek/markdown/?' do markdown :sayfa, :layout_engine => :erb, :layout => :genel3 end # render için erb motorunu kullanıyoruz
Filtreler before '/sayfa/3/?' do @before_param = "Bu değişken -before- da set edildi" end get '/sayfa/3/?' do @saat = Time.now.strftime("%I:%M:%S") @page_title = "Bu sayfa :layout ve css kullanıyor" erb :sayfa, :layout => :genel2 end
Yardımcı Fonksiyonlar (Helpers) View ve Handler’larda kullanılır. helpers do def h(text) Rack::Utils.escape_html(text) end end # application.rb <%= h @username %> # view/erb
pass ve halt get '/tahmin/:kim/?' do pass unless params[:kim] == 'vigo' "Doğru cevap!" end get '/tahmin/*/?' do "Hayır bilemedin!" end http://127.0.0.1:9393/tahmin/vigo/ get '/konferans1/:hangisi/?' do halt unless params[:hangisi] == 'jspyconf' "Evet doğru konferans!" end http://127.0.0.1:9393/konferans1/jspyconf
Diğer halt durumları get '/konferans2/:hangisi/?' do halt 404 unless params[:hangisi] == 'jspyconf' "Evet doğru konferans!" end get '/konferans3/:hangisi/?' do halt [403, "Yetkiniz yok"] unless params[:hangisi] == 'jspyconf' "Evet doğru konferans!" end Hata kodu ve ilave mesaj belirtmek
Özelleştirilmiş Hatalar disable :show_exceptions error do mesaj = env['sinatra.error'].message "Hata mesajı: #{mesaj}" end class CustomError < StandardError; end error CustomError do mesaj = env['sinatra.error'].message "Bu CustomError, mesajı da #{mesaj}" end
Özelleştirilmiş Hatalar get '/ozel-hata/1/' do raise StandardError, "StandardError raise ettik" end get '/ozel-hata/2/' do raise CustomError, "CustomError raise ettik" end
Test group :test do gem 'rack-test' end # Gemfile OUTER_APP = Rack::Builder.parse_file('config.ru').first class TestApp < Test::Unit::TestCase include Rack::Test::Methods def app OUTER_APP end def test_sample_page get '/test/amacli/1/' assert last_response.ok? assert_equal "JsPyConf çok güzel!", last_response.body end end # tests.rb
Deployment # config.ru # application.rb # encoding: utf-8 require "./application.rb" run MyApp # encoding: utf-8 require 'rubygems' require 'bundler' Bundler.require # gerekli diğer require'lar... class MyApp < Sinatra::Base get '/' do "Merhaba" end run! if app_file == $0 end # encoding: utf-8 source "https://rubygems.org" ruby "1.9.3" group :development do gem 'thin' gem 'shotgun' end group :test do gem 'rack-test' end gem 'sinatra' gem 'sass' gem 'rdiscount' # Gemfile
DataMapper require 'sqlite3' require 'dm-core' require 'dm-timestamps' configure :development do DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/my_database.db") end class Blog include DataMapper::Resource property :id, Serial property :title, String property :content, Text property :url, String property :is_active, Boolean property :created_at, DateTime property :updated_at, DateTime end get '/blog/:post_id' do @post = Blog.get(params[:post_id]) erb :post_detail end sqlite3