Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

FRANK SINATRA

Slide 3

Slide 3 text

Sinatra ? Ruby ile hızlı ve kolay bir şekilde web uygulaması geliştirmek için hazırlanmış bir DSL’dir. http://www.sinatrarb.com/

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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ı

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

“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

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

HTTP Metodları GET POST PUT DELETE PATCH OPTIONS LINK UNLINK

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

Sayfalar (Views) # views/sayfa.erb

Merhaba

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

Ş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

Slide 24

Slide 24 text

Şablonlar (Templates) Sass ve Markdown # views/genel3.erb <%= @page_title %>

genel.erb

<%= yield %>

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

Filtreler before Request’den önce çalışır. after Request’den sonra çalışır. before do headers "Content-Type" => "text/html; charset=utf-8" end

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

Ö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

Slide 37

Slide 37 text

Ö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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

Deployment Apache $ (sudo) passenger-install-apache2-module ServerName example.com DocumentRoot /path/to/example.com/public AllowOverride all Options -MultiViews

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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