Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Merhaba "Sinatra"

Merhaba "Sinatra"

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

Uğur Özyılmazel

March 31, 2013
Tweet

More Decks by Uğur Özyılmazel

Other Decks in Programming

Transcript

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

    View Slide

  2. FRANK SINATRA

    View Slide

  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/

    View Slide

  4. DSL ?
    Belirli bir problemi çözmek ya da işlemi
    yapmak için geliştirilmiş / hazırlanmış
    dil.

    View Slide

  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

    View Slide

  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ı

    View Slide

  7. Dan Benjamin
    “RACK’den fazla
    RAILS’den az!”
    Peepcode - Meet Sinatra
    “More than RACK, Less than RAILS”

    View Slide

  8. Kurulum
    $ gem install sinatra
    * Mart 2013 itibariyle son sürüm : 1.4.2

    View Slide

  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

    View Slide

  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

    View Slide

  11. View Slide

  12. HTTP Metodları
    GET
    POST
    PUT
    DELETE
    PATCH
    OPTIONS
    LINK
    UNLINK

    View Slide

  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

    View Slide

  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

    View Slide

  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 => '[email protected]' }.to_json
    end

    View Slide

  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

    View Slide

  17. Sayfalar (Views)
    # views/sayfa.erb
    Merhaba

    Saat <%= @saat %>

    # server.rb
    get '/sayfa/?' do
    @saat = Time.now.strftime("%I:%M:%S")
    erb :sayfa
    end

    View Slide

  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

    Kullanıcı adı girin



    <% if @username %>
    Göndermiş olduğunuz kullanıcı adı:
    <%= h @username %>
    <% end %>

    # views/post_form.erb
    Helper

    View Slide

  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;
    }




    <%= @page_title %>



    genel.erb
    <%= yield %>


    # views/genel2.erb

    View Slide

  20. Şablonlar (Templates)
    • Haml
    • Erb
    • Builder
    • Nokogiri
    • Liquid
    • Markdown
    • Textile
    • Rdoc
    • Sass / SCSS
    • Less
    • Coffe
    • Stylus

    View Slide

  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




    <%= @page_title %>


    genel.erb
    <%= yield %>


    View Slide

  22. View Slide

  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

    View Slide

  24. Şablonlar (Templates)
    Sass ve Markdown
    # views/genel3.erb




    <%= @page_title %>



    genel.erb
    <%= yield %>


    View Slide

  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%)

    View Slide

  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

    View Slide

  27. Filtreler
    after ve before’da set edilen değişkenler
    tüm “route”larda kullanılabiliyor.

    View Slide

  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

    View Slide

  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
    <%= h @username %>
    # view/erb

    View Slide

  30. pass ve halt
    halt
    Tamamen dur!
    pass
    Uygun olan bir sonraki route’a geç

    View Slide

  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

    View Slide

  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

    View Slide

  33. Özelleştirilmiş 404
    not_found do
    "Aradığınız sayfa bulunamadı!"
    end
    Tamamen özelleştirmek...
    not_found do
    erb :ozel_404
    end

    View Slide

  34. Yönlerdirmek: redirect
    redirect URL, StatusCode
    get '/google' do
    redirect "http://google.com"
    # redirect "/foo", 301
    end

    View Slide

  35. Hata Yakalamak
    error 403 do
    "Giriş Yasak"
    end
    get '/gizli' do
    403
    end
    error 400..510 do
    "Pek çok hatayı yakaladık"
    end

    View Slide

  36. Ö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

    View Slide

  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

    View Slide

  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

    View Slide

  39. Session
    enable :sessions
    Konfigürasyon seviyesinde
    session['key'] = "value"
    get('/') {
    "Merhaba #{session['user_name']}."
    }

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  45. Deployment
    Apache
    $ (sudo) passenger-install-apache2-module

    ServerName example.com
    DocumentRoot /path/to/example.com/public

    AllowOverride all
    Options -MultiViews


    View Slide

  46. Daha Fazla...
    • sinatra-contrib
    • DataMapper (Veritabanı Entegrasyonu)
    • Modüler Uygulamalar
    • Streaming / Long Polling
    • Middleware Geliştirmek
    • Extension Geliştirmek

    View Slide

  47. DataMapper
    $ gem install data_mapper
    $ gem install dm-sqlite-adapter
    $ gem install dm-mysql-adapter
    $ gem install dm-postgres-adapter

    View Slide

  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

    View Slide

  49. DataMapper
    class Post
    has n, :comments
    end
    class Comment
    belongs_to :post
    end
    DataMapper.auto_migrate!

    View Slide

  50. Kimler Kullanıyor?
    • Heroku
    • Github
    • Apple
    • BBC
    • Linkedin
    • Engine Yard
    • Stanford
    • Red Hat
    • Travis CI
    • Songbird

    View Slide

  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

    View Slide

  52. Kaynak Kod
    https://github.com/vigo/jspy2013-sinatra
    http://jspy2013-sinatra.herokuapp.com

    View Slide

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

    View Slide