3. Sinatra ?
Ruby ile hızlı ve kolay bir
şekilde web uygulaması
geliştirmek için hazırlanmış bir
DSL’dir.
http://www.sinatrarb.com/
4. DSL ?
Belirli bir problemi çözmek ya da işlemi
yapmak için geliştirilmiş / hazırlanmış
dil.
5. 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
Mizera
ny
6. 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ı
9. Yardımcı Araçlar
•
•
shotgun
thin
$ 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
10. “Merhaba Dünya”
# application.rb
require 'rubygems'
require 'sinatra'
get '/' do
"Merhaba Dünya! saat: #{Time.now}"
end
$ ruby application.rb
# default http://localhost:4567
$ shotgun application.rb
# http://127.0.0.1:9393
13. Yakalayıcılar (Handlers)
get '/merhaba/:user_name' do
"Merhaba #{params[:user_name]}!"
end
http://127.0.0.1:9393/merhaba/jspyconf
http://127.0.0.1:9393/merhaba/vigo/numaran/11
get '/merhaba/*/numaran/*' do
"#{params[:splat][0]}, #{params[:splat][1]}"
end
14. Params, Splat ve RegExp Kullanımı
http://127.0.0.1:9393/indir/resim.jpg
get '/indir/*.*' do |file, ext|
"Dosya: #{file}, Tipi: #{ext}"
end
http://127.0.0.1:9393/kazanan/vigo
http://127.0.0.1:9393/kazanan/vigo/1
get '/kazanan/:user/?:id?' do
"Kazanan #{params[:user]}, id var mı? #{!params[:id].nil?}"
end
http://127.0.0.1:9393/kullanici/vigo
http://127.0.0.1:9393/kullanici/vigo/1
get %r{/kullanici/([w]+)/?(d+)?} do
"Yakalananlar: #{params[:captures]}"
end
15. 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 => 'hello@jspyconf.org' }.to_json
end
16. 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
23. Şablonlar (Templates)
Sass ve Markdown
# sass/*.sass yakalamak için
get '/sass/*.sass' do
content_type 'text/css', :charset => 'utf-8'
sass params[:splat].first.to_sym,
:style => :expanded,
:views => "#{settings.root}/sass"
end
# render için erb motorunu kullanıyoruz
get '/sayfa/ornek/markdown/?' do
markdown :sayfa, :layout_engine => :erb, :layout => :genel3
end
28. 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
29. Yardımcı Fonksiyonlar (Helpers)
View ve Handler’larda kullanılır.
# application.rb
helpers do
def h(text)
Rack::Utils.escape_html(text)
end
end
# view/erb
<strong><%= h @username %></strong></p>
31. pass ve halt
http://127.0.0.1:9393/tahmin/vigo/
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/konferans1/jspyconf
get '/konferans1/:hangisi/?' do
halt unless params[:hangisi] == 'jspyconf'
"Evet doğru konferans!"
end
32. Diğer halt durumları
Hata kodu ve ilave mesaj belirtmek
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
35. Hata Yakalamak
error 403 do
"Giriş Yasak"
end
get '/gizli' do
403
end
error 400..510 do
"Pek çok hatayı yakaladık"
end
36. Özelleştirilmiş Hatalar
disable :show_exceptions
error do
mesaj = env['sinatra.error'].message
"Hata mesajı: <strong>#{mesaj}</strong>"
end
class CustomError < StandardError; end
error CustomError do
mesaj = env['sinatra.error'].message
"Bu <strong>CustomError</strong>,
mesajı da <strong>#{mesaj}</strong>"
end
41. Test
# Gemfile
group :test do
gem 'rack-test'
end
# tests.rb
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
44. Deployment
# config.ru
# encoding: utf-8
require "./application.rb"
run MyApp
# application.rb
# 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
# Gemfile
# 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'
48. DataMapper
sqlite3
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