merhaba sinatra

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

Upload: ugur-oezyilmazel

Post on 15-Jan-2015

242 views

Category:

Technology


1 download

DESCRIPTION

Ruby ile geliştirilmiş mikro webframework'ü Sinatra ile tanışmak! Kurulumu, kullanım ve diğer özellikleri.

TRANSCRIPT

Page 1: Merhaba Sinatra

MERHABA “SİNATRA”Uğur Özyılmazel

http://ugur.ozyilmazel.com | @ugurozyilmazel

Page 2: Merhaba Sinatra

FRANK SINATRA

Page 3: Merhaba Sinatra

Sinatra ?

Ruby ile hızlı ve kolay bir şekilde web uygulaması geliştirmek için hazırlanmış bir DSL’dir.

http://www.sinatrarb.com/

Page 4: Merhaba Sinatra

DSL ?

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

Page 5: Merhaba Sinatra

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

Page 6: Merhaba Sinatra

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ı

Page 7: Merhaba Sinatra

Dan Benjamin

“RACK’den fazlaRAILS’den az!”

Peepcode - Meet Sinatra

“More than RACK, Less than RAILS”

Page 8: Merhaba Sinatra

Kurulum

$ gem install sinatra

* Mart 2013 itibariyle son sürüm : 1.4.2

Page 9: Merhaba Sinatra

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

Page 10: Merhaba Sinatra

“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

Page 11: Merhaba Sinatra
Page 12: Merhaba Sinatra

HTTP Metodları

GET

POST

PUT

DELETE

PATCH

OPTIONS

LINK

UNLINK

Page 13: Merhaba Sinatra

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

Page 14: Merhaba Sinatra

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/vigohttp://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/vigohttp://127.0.0.1:9393/kazanan/vigo/1

Page 15: Merhaba Sinatra

Duruma Bağlı Yakalama (Conditions):agent# AppleWebKit/536.28.10# Sadece AppleWebKit tarayıcıları içinget '/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ışmazget '/admin', :host_name => /^local/ do "Sadece adminler girebilir!"end

:providesget '/test_provide', :provides => :json do pass unless request.accept? 'application/json' { :username => 'vigo', :email => '[email protected]' }.to_jsonend

Page 16: Merhaba Sinatra

Kendi Durumumuz Oluşturalım

set(:ihtimal) { |value| condition { rand <= value } }get '/piyango', :ihtimal => 0.1 do "Tebrikler kazandınız!"endget '/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 endendget "/sistem/giris/?" do "Bu sayfaları görüntülemek için sisteme giriş yapmanız gerekiyor!"endget "/sistem/profil/?", :test_auth => [:user, :guest] do "Profil bilgileri"endget "/sistem/admin/?", :test_auth => :admin do "Sadece admin olanlar görebiliyor"end

Page 17: Merhaba Sinatra

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 :sayfaend

Page 18: Merhaba Sinatra

Post İşlemi# application.rb

get '/post/test/?' do erb :post_form, :layout => :genelendpost '/post/test/?' do @username = params[:username] erb :post_form, :layout => :genelend

<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

Page 19: Merhaba Sinatra

Statik Dosyalar# application.rbget '/sayfa/3/?' do @saat = Time.now.strftime("%I:%M:%S") @page_title = "Bu sayfa :layout ve css kullanıyor" erb :sayfa, :layout => :genel2end

# 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

Page 20: Merhaba Sinatra

Şablonlar (Templates)

• Haml

• Erb

• Builder

• Nokogiri

• Liquid

• Markdown

• Textile

• Rdoc

• Sass / SCSS

• Less

• Coffe

• Stylus

Page 21: Merhaba Sinatra

Mizanpaj (Layout)# application.rbget '/sayfa/2/?' do @saat = Time.now.strftime("%I:%M:%S") @page_title = "Bu sayfa :layout kullanıyor" erb :sayfa, :layout => :genelend

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

Page 22: Merhaba Sinatra
Page 23: Merhaba Sinatra

Ş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 => :genel3end

# render için erb motorunu kullanıyoruz

Page 24: Merhaba Sinatra

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

Page 25: Merhaba Sinatra

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

Page 26: Merhaba Sinatra

FiltrelerbeforeRequest’den önce çalışır.

afterRequest’den sonra çalışır.

before do headers "Content-Type" => "text/html; charset=utf-8"end

Page 27: Merhaba Sinatra

Filtreler

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

Page 28: Merhaba Sinatra

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 => :genel2end

Page 29: Merhaba Sinatra

Yardımcı Fonksiyonlar (Helpers)

View ve Handler’larda kullanılır.

helpers do def h(text) Rack::Utils.escape_html(text) endend

# application.rb

<strong><%= h @username %></strong></p>

# view/erb

Page 30: Merhaba Sinatra

pass ve halt

haltTamamen dur!

passUygun olan bir sonraki route’a geç

Page 31: Merhaba Sinatra

pass ve halt

get '/tahmin/:kim/?' do pass unless params[:kim] == 'vigo' "Doğru cevap!"endget '/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

Page 32: Merhaba Sinatra

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

Page 33: Merhaba Sinatra

Özelleştirilmiş 404

not_found do "Aradığınız sayfa bulunamadı!"end

Tamamen özelleştirmek...

not_found do erb :ozel_404end

Page 34: Merhaba Sinatra

Yönlerdirmek: redirect

redirect URL, StatusCode

get '/google' do redirect "http://google.com" # redirect "/foo", 301end

Page 35: Merhaba Sinatra

Hata Yakalamakerror 403 do "Giriş Yasak"endget '/gizli' do 403end

error 400..510 do "Pek çok hatayı yakaladık"end

Page 36: Merhaba Sinatra

Özelleştirilmiş Hatalardisable :show_exceptionserror do mesaj = env['sinatra.error'].message "Hata mesajı: <strong>#{mesaj}</strong>"end

class CustomError < StandardError; enderror CustomError do mesaj = env['sinatra.error'].message "Bu <strong>CustomError</strong>, mesajı da <strong>#{mesaj}</strong>"end

Page 37: Merhaba Sinatra

Ö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

Page 38: Merhaba Sinatra

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_exceptionsend

configure :development, :test do enable :loggingend

Page 39: Merhaba Sinatra

Session

enable :sessions

Konfigürasyon seviyesinde

session['key'] = "value"get('/') { "Merhaba #{session['user_name']}."}

Page 40: Merhaba Sinatra

Session

Pooling

Cookieuse 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

Page 41: Merhaba Sinatra

Test

group :test do gem 'rack-test'end

# Gemfile

OUTER_APP = Rack::Builder.parse_file('config.ru').firstclass 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 endend

# tests.rb

Page 42: Merhaba Sinatra

TestRack::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

Page 43: Merhaba Sinatra

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

Page 44: Merhaba Sinatra

Deployment# config.ru

# application.rb

# encoding: utf-8require "./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 == $0end

# encoding: utf-8source "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

Page 45: Merhaba Sinatra

DeploymentApache

$ (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>

Page 46: Merhaba Sinatra

Daha Fazla...

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

Page 47: Merhaba Sinatra

DataMapper

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

Page 48: Merhaba Sinatra

DataMapperrequire '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, DateTimeend

get '/blog/:post_id' do @post = Blog.get(params[:post_id]) erb :post_detailend

sqlite3

Page 49: Merhaba Sinatra

DataMapper

class Post has n, :commentsend

class Comment belongs_to :postend

DataMapper.auto_migrate!

Page 50: Merhaba Sinatra

Kimler Kullanıyor?

• Heroku• Github• Apple• BBC• Linkedin

• Engine Yard• Stanford• Red Hat• Travis CI• Songbird

Page 51: Merhaba Sinatra

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

Page 52: Merhaba Sinatra

Kaynak Kod

https://github.com/vigo/jspy2013-sinatra

http://jspy2013-sinatra.herokuapp.com

Page 53: Merhaba Sinatra

Teşekkürler

@ugurozyilmazel

@vigobronx

http://ugur.ozyilmazel.com