Merhaba "Sinatra"

Merhaba "Sinatra"

Ruby web framework'ü Sinatra'yı tanıyalım!

033485f7e18823d4ccabb24e5cb4935f?s=128

Uğur Özyılmazel

March 31, 2013
Tweet

Transcript

  1. MERHABA “SİNATRA” Uğur Özyılmazel http://ugur.ozyilmazel.com | @ugurozyilmazel

  2. FRANK SINATRA

  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 Mizerany
  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ı
  7. Dan Benjamin “RACK’den fazla RAILS’den az!” Peepcode - Meet Sinatra

    “More than RACK, Less than RAILS”
  8. Kurulum $ gem install sinatra * Mart 2013 itibariyle son

    sürüm : 1.4.2
  9. 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
  10. “Merhaba Dünya” require 'rubygems' require 'sinatra' get '/' do "Merhaba

    Dünya! saat: #{Time.now}" end # application.rb $ ruby application.rb # default http://localhost:4567 $ shotgun application.rb # http://127.0.0.1:9393
  11. None
  12. HTTP Metodları GET POST PUT DELETE PATCH OPTIONS LINK UNLINK

  13. 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
  14. 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
  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
  17. Sayfalar (Views) # views/sayfa.erb <h1>Merhaba</h1> <div> Saat <%= @saat %>

    </div> # server.rb get '/sayfa/?' do @saat = Time.now.strftime("%I:%M:%S") erb :sayfa end
  18. 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 <form action="?" method="post" accept-charset="utf-8"> <p><strong>Kullanıcı adı girin</strong><br/> <input type="test" name="username" value=""/></p> <p><input type="submit" value="Gönder &rarr;"/></p> <% if @username %> <p>Göndermiş olduğunuz kullanıcı adı: <strong><%= h @username %></strong></p> <% end %> </form> # views/post_form.erb Helper
  19. Statik Dosyalar # application.rb 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 # public/css/base.css body { background: #555; color: #ff0; font-family: Helvetica, Arial; margin: 20px; padding: 0; } h1 { color: #fff; } <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title><%= @page_title %></title> <link href="/css/base.css" rel="stylesheet" /> </head> <body> <h1>genel.erb</h1> <%= yield %> </body> </html> # views/genel2.erb
  20. Şablonlar (Templates) • Haml • Erb • Builder • Nokogiri

    • Liquid • Markdown • Textile • Rdoc • Sass / SCSS • Less • Coffe • Stylus
  21. Mizanpaj (Layout) # application.rb get '/sayfa/2/?' do @saat = Time.now.strftime("%I:%M:%S")

    @page_title = "Bu sayfa :layout kullanıyor" erb :sayfa, :layout => :genel end # views/genel.erb <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title><%= @page_title %></title> </head> <body> <h1>genel.erb</h1> <%= yield %> </body> </html>
  22. None
  23. Ş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
  24. Şablonlar (Templates) Sass ve Markdown # views/genel3.erb <!DOCTYPE html> <html

    lang="en"> <head> <meta charset="utf-8"> <title><%= @page_title %></title> <link href="/sass/stil.sass" rel="stylesheet" /> </head> <body> <h1>genel.erb</h1> <%= yield %> </body> </html>
  25. Şablonlar (Templates) Sass ve Markdown # views/sayfa.markdown # Bu H1

    ## Bu H2 Bu pre ... Bu paragraf... def foo(user) "#{user}" end # sass/stil.sass $color: #00f $h1_color: adjust-hue($color, 270deg) $fonts: Helvetica, Arial body background-color: adjust-hue($color, 20deg) color: darken($h1_color, 20%) font-family: $fonts margin: 40px h1 color: $h1_color pre border: 1px solid darken($color, 20) padding: 20px background-color: darken($color, 24) code line-height: 1.5em color: darken($h1_color, 10%)
  26. Filtreler before Request’den önce çalışır. after Request’den sonra çalışır. before

    do headers "Content-Type" => "text/html; charset=utf-8" end
  27. Filtreler after ve before’da set edilen değişkenler tüm “route”larda kullanılabiliyor.

  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. helpers do def

    h(text) Rack::Utils.escape_html(text) end end # application.rb <strong><%= h @username %></strong></p> # view/erb
  30. pass ve halt halt Tamamen dur! pass Uygun olan bir

    sonraki route’a geç
  31. 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
  32. 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
  33. Özelleştirilmiş 404 not_found do "Aradığınız sayfa bulunamadı!" end Tamamen özelleştirmek...

    not_found do erb :ozel_404 end
  34. Yönlerdirmek: redirect redirect URL, StatusCode get '/google' do redirect "http://google.com"

    # redirect "/foo", 301 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
  37. Ö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
  38. Konfigürasyon :test :development :production # http://www.sinatrarb.com/intro.html#Configuration configure do # set

    :option, 'value' # enable :option # disable :option enable :logging disable :show_exceptions end configure :development, :test do enable :logging end
  39. Session enable :sessions Konfigürasyon seviyesinde session['key'] = "value" get('/') {

    "Merhaba #{session['user_name']}." }
  40. Session Pooling Cookie use Rack::Session::Cookie, :key => 'rack.session', :domain =>

    'foo.com', :path => '/', :expire_after => 2592000, # Saniye :secret => 'burayı_düzenle' use Rack::Session::Pool, :expire_after => 2592000
  41. 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
  42. Test Rack::Test::Methods :request :get :post :put :delete :options :head :follow_redirect!

    :header :set_cookie :clear_cookies :authorize :basic_authorize :digest_authorize :last_response :last_request
  43. Deployment • Apache • Nginx • Standalone Phusion Passenger Heroku

    $ sudo gem install passenger https://toolbelt.heroku.com/ git push heroku https://devcenter.heroku.com/articles/rack#frameworks
  44. 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
  45. Deployment Apache $ (sudo) passenger-install-apache2-module <VirtualHost *:80> ServerName example.com DocumentRoot

    /path/to/example.com/public <Directory /path/to/example.com/public> AllowOverride all Options -MultiViews </Directory> </VirtualHost>
  46. Daha Fazla... • sinatra-contrib • DataMapper (Veritabanı Entegrasyonu) • Modüler

    Uygulamalar • Streaming / Long Polling • Middleware Geliştirmek • Extension Geliştirmek
  47. DataMapper $ gem install data_mapper $ gem install dm-sqlite-adapter $

    gem install dm-mysql-adapter $ gem install dm-postgres-adapter
  48. 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
  49. DataMapper class Post has n, :comments end class Comment belongs_to

    :post end DataMapper.auto_migrate!
  50. Kimler Kullanıyor? • Heroku • Github • Apple • BBC

    • Linkedin • Engine Yard • Stanford • Red Hat • Travis CI • Songbird
  51. Kaynaklar • http://www.sinatrarb.com/ • http://recipes.sinatrarb.com/ • http://sinatra-book.gittr.com/ • http://modrails.com •

    http://datamapper.org/getting-started.html • https://peepcode.com/products/sinatra * • https://tutsplus.com/course/simple-sinatra/ * * Ücretli servisler
  52. Kaynak Kod https://github.com/vigo/jspy2013-sinatra http://jspy2013-sinatra.herokuapp.com

  53. Teşekkürler @ugurozyilmazel @vigobronx http://ugur.ozyilmazel.com