1. Rails 2.0 - web aplikacje jeszcze bardziej
subiektywnie
aka. quot;A właśnie, że nie zreferuje ChangeLoga!quot;
Jarosław Rzeszótko, http://www.stifflog.com/
2. Słowa zajawki
- Rails 2 nie jest rewolucją z punktu widzenia technologii
- Rails 2 jest finalną opinią DHH i kolegów na temat tworzenia
aplikacji internetowych
- Lista zmian w Rails 2 jest jedynie kropką nad... no właśnie, nad
czym?
- Większość zmian dotyczy quot;zasobówquot; i w komentarzach na temat
wydania te własnie zmiany najczęściej sa pomijane lub kwitowane
ziewnięciem...
- Najsłabiej rozumiany i najtrudniejszy aspekt Railsów, proszę więc
o skupienie
- A teraz czas na kontekst, który nieco zdominował tą prezentację...
3. Architektura aplikacji sieciowych
- Nowoczesne narzędzia programistyczne abstrahuja większość
szczegółów, która może zostać potraktowana jako quot;niskopoziomychquot;
jak np. sposób komunikacji z użyciem protokołu HTTP
- Dla całej reszty świata nasza aplikacja jest widoczna jako zestaw
adresów URI wykorzystywalnych za pomocą protkołu HTTP
- Nie możemy więc świadomie tworzyć aplikacji WWW, ani rozpatrywać
narzędzi służących do tworzenia takich aplikacji, bez zrozumienia
fundamentalnych aspektów tejże globanej sieci
4. Czym jest World Wide Web?
- Wg. definicji Tim'a Bernersa Lee - współdzieloną przestrzenią
informacyjną w której zarówno ludzie jak i maszyny mogą się
komunikować
- Prościej - siecią połączonych quot;dokumentówquot;
- Komunikacja maszyna<->maszyna staję się coraz ważniejsza
- Przykłady: mashupy, Yahoo Pipes, otwarte platformy, widgety,
API, mikroformaty, semantyczna sieć, rozmaite programy
crawlujące
- Moja opinia: prawdziwym krokiem naprzód w dziedzinie przepływu
informacji nie są ani nie będą serwisy społecznościowe, a
umożliwienie komputerom głębszego rozumienia danych, które w
olbrzymiej ilości udostepniamy
- quot;Komputer, przynieś śniadanie!quot;
5. Czym jest URI?
- Unikalny identyfikator każdego quot;bytuquot; w World Wide Web
- Spoiwem, który łączy poszczególne zasoby, w to, co quot;bywa
powszechnie nazywane Internetemquot;
- Początkowo stosowany w odniesieniu dokumentów, został uogólniony
na szerszy zakres obiektów
- quot;Resourcequot; w quot;Unique Resource Identifierquot;
quot;Zasobem może być wszystko co tylko posiada tożsamość. Prostymi
przykładami może być dokument elektroniczny, obrazek, serwis (np.
'dzisiejszy raport pogodowy dla Los Angeles' albo kolekcja innych
zasobów.quot; - RFC2396
- Treść dokumentu może się zmienić, jego URI - nie powinien
6. Czym jest HTTP?
- Protokołem, opisującym w jaki sposób klient (przeglądarka, inny
program komputerowy, itp.) komunikuje się z serwerem (komputerem i
programem udostępniającym dane, które chcę pobrać klient)
- Dane te są hipertekstowe - zawierają odnośniki do innych danych,
powiązanych z tymi, które właśnie pobraliśmy
- To połączenia pomiędzy danymi nadają sieci jej obecny kształt
- Protokół ten opisuje także w jaki sposób klienci mogą wydać żadanie
utworzenia, modyfikacji lub usunięcia danych
- Nad sprawnym działaniem czuwa wielu niewidzalnych gości
pośredniczących w połączeniu pomiędzy klientem a serwerem, którzy
sprawiają że WWW działa szybciej, bardziej niezawodnie, a przede
wszystkim że dało się je wyskalować do tak wielkiej skali np.
serwery proxy
7. Czym jest REST?
- Stylem architektonicznym - czyli zestawem wymagań, jakie musi
spełnić dana architektura aplikacji, by mogła zostać nazwana
RESTową
- Styl ten został ustalony i zastosowany do standardów HTTP 1.1 i
URI, kiedy okazało się, że sieć nie spełnia nowych wymagań
powstałych na skutek popularyzacji WWW i coraz bardziej
rozbudowanych aplikacji działających w tej sieci.
- Formalnej i jednocześnie jedynej sensownej definicji dostarcza
praca doktorska Roy Fieldinga, twórcy RESTu, współautora
specyfikacji HTTP 1.1 i URI
- ABC RESTu:
- Zasoby
- Identyfikatory zasobów
- Reprezentacje zasobów
8. Czym jest REST #2
Cechy RESTu w ogólności (niekoniecznie w odniesieniu do WWW):
- Architektura klient-serwer
- Bezstanowość
- Zapamiętywanie zapytań (cache)
- Jednolity interfejs
- Wielowarstwowy system
Dla twórców aplikacji webowych:
- Najważniejsze zaleta: zmusza do zastanowienia się nad projetkem
swojej aplikacji w świetle HTTP/URI
- Minimalizujemy użycie stanu, każde żądanie powinno zawierać
wszystkie informacje potrzebne do jego zrealizowania
- Obiekty, z którymi pracuje nasza aplikacja mapujemy na zasoby
- Każdy zasób powinien posiadać unikalny adres URI
- Zmiany stanu definiujemy za pomocą odpowiednich typów żadań HTTP
wysyłanych do odpowiednich adresów URI
- Stan będacy rezultatem danego wywołania zwracamy z użyciem kodów
odpowiedzi i nagłówków HTTP
- Podejście deklaratywne, zamiast imperatywnego
9. Esencja RESTu #1
quot;To co czyni HTTP znacząco różnym od mechanizmów zdalnego
wywoływania procedur jest to, że żądania są kierowane do zasobów
przy użyciu uniwersalnego interfejsu ze standardową semantyką
który może być interpretowany przez warstwy pośredniczące prawie
tak dobrze jak przez komputery bezpośrednio uczestniczące w
danym połączeniu. W rezultacie otrzymujemy aplikację, która
pozwala na użycie warstw transformacji i pośrednictwa które są
niezależne od źródła informacji, co jest bardzo ważne w
skalowalnym systemie informatycznym na skalę Internetu. W
odróżnieniu, mechanizmy zdalnego wywoływania poleceń
zdefiniowane są w kontekście API poszczególnych języków, a nie
komunikacji sieciowej.quot;
Roy Fielding,
quot;Architectural Styles and the Design of Network-based Software Architecturesquot;
10. Esencja RESTu #2
- quot;Uniwersalny interfejs ze standardową semantykąquot;
- Jednolity sposób na pobieranie informacji zarówno przez ludzi,
jak i przez maszyny/programy komputerowe
- Proste tworzenie elastycznych bibliotek
- Składnia zrozumiała dla programów komputerowych, działających
na skalę Internetu
- Alternatywy sprawiają, że składanie wywołań do różnych
aplikacji nie ma żadnego wspólnego mianownika
11. Esencja RESTu #3
- quot;Warstwy transformacji i pośrednictwa które są niezależne od źródła
informacjiquot;
- Największe zalety RESTu nie odnoszą się bezpośrednio do klientów
- Wiele zyskują elementy łączące - np. serwery proxy
- W alternatywnych podejściach funkcjonowanie tych elementów jest
utrudnione lub uniemożliwione
- SOAP używa HTTP jako transportu by omijać firewalle...
- Dlaczego brak stanu może być pożądany?
- Ułatwione zadanie mają także np. wyszukiwarki
12. Rails - referencyjny framework dla RESTowych aplikacji?
- quot;Tak wyszłoquot; - Rails nie był projektowany jako RESTowy framework
- Wraz z rozwojem każdego projektu zyskującego sporą popularność
pojawia się pewien zestaw quot;najlepszych praktykquot;
- Najważniejszą taką praktyką w Rails stał się sposób rozkładania
aplikacji pomiędzy fundamentalne warstwy - model i kontroler.
Rozrastające się projekty w Rails prowadzone przez dobrych
programistów składały się najczęściej z:
- Bardzo quot;cienkichquot; kontrolerów, których wieksza część
funkcjonalności mapowała adresy url na odpowiednie akcje na
modelach - odczytaj, utwórz, skasuj, zmodyfikuj, oraz
odpowiednio wybierające widok
- quot;Tłustequot; modele, zawierające CAŁĄ logikę biznesową
- Na wiekszość modeli przypadały osobne kontrolery
13. Rails - referencyjny framework dla RESTowych aplikacji #2
- To wynika z MVC i dla doświadczonego programisty może wydawać się
oczywiste, jednak często nie jest to posunięte odpowiednio daleko:
- Jeśli twoje kontrolery obsługują więcej niż jeden model i modele
te nie są w relacji rodzic-dzieci, jeśli wykonują jakiekolwiek
operacje nie związane bezpośrednio z obsługą żądania HTTP -
są duże szanse, że robisz coś źle
- Nie trudno zauważyć, że większość takich kontrolerów (w końcu
zajmujących się głównie odpowiadaniem na żadania HTTP i wyborem
reprezentacji dla modelu!) i ich akcji (CRUD) naturalnie przekłada
się na zbiór zasobów i operacji zdefiniowanych na nich za pomocą
semantyki HTTP - GET, PUT, POST, DELETE
- Wobec czego, Railsy 1.2 wprowdziły już dość rozbudowane, ale jeszcze
niedopracowane wsparcie dla budowy RESTowych aplikacji
- Railsy 2.0 pozwalają zapomnieć o wszelkich niedogodnościach
związanych z serwowaniem treści z RESTowej aplikacji do quot;durnychquot;
klientów, zachowując pozostałe zalety takich architektur
14. Rails - referencyjny framework dla RESTowych aplikacji #3
- Ani Rails, ani REST nie są quot;srebrnymi pociskamiquot;
- I Rails i REST były tworzone ze względu na praktyczne potrzeby ich
autorów z budowaniem aplikacji internetowych - są zoptymalizowane
dla znaczącej większości zastosowań
- Alternatywne podejścia jak SOAP mają swoje miejsce i przewagi nad
RESTem, ale nie w zastosowaniach do jakich przeznaczony jest
Rails, czyli takich, którymi większość z nas tutaj się zajmuje
- Używając Railsów bez dokładnego zrozumienia mechanizmów RESTowych
tracimy połowe obrazu i sporo skuteczności
- A że wiele osób tak ich własnie używa, jako quot;drop-inquot;, zamiennik
dla PHP, umożliwiający jeszcze szybsze klepanie...
- Więc o tym mówimy
15. Zmiany w Rails 2.0
- Wydaje mi się, że większa część listy zmian w Rails 2, jak i zresztą
w Rails 1.2 zaczyna mieć dla studiującego sens dopiero po
zrozumieniu wszystkiego co wcześniej powiedziałem
- Na poparcie moich słów:
quot;As you might have gathered, Action Pack in Rails 2.0 is all about
getting closer with HTTP and all its glory.quot;
Ojciec Założyciel David Heinemeier Hansson
16. Zmiany w Rails 2.0 - ActiveResource
require 'activeresource'
# Twoja stara postuje XML do quot;/statuses.jsonquot;
class ActiveResource::Base
def to_json
{ self.class.to_s.downcase => attributes }.to_json
end
def parametrize
method((quot;to_quot; + self.class.format.extension).to_sym).call
end
def create
returning connection.post(collection_path, parametrize, self.class.headers) do
|response|
self.id = id_from_response(response)
load_attributes_from_response(response)
end
end
end
class BlipResource < ActiveResource::Base
self.site = 'http://foo:dupa.8@localhost/'
self.format = :json
end
class User < BlipResource; end
class Update < BlipResource; end
class Status < BlipResource; end
@user = User.find(:id => quot;fooquot;)
@statuses = Status.find(:all, :user_id => 'foo', :params => {:limit => 4})
@new_status = Status.create(:body => quot;Witaj świecie!quot;)
17. Zmiany w Rails 2.0 - Autentykacja HTTP
class PostsController < ApplicationController
before_filter :authenticate, :except => [ :index ]
def index
render :text => quot;Dla wszystkichquot;
end
def edit
render :text => quot;Tylko dla znajomych :>quot;
end
private
def authenticate
authenticate_or_request_with_http_basic do |user_name, password|
user = User.find_by_name(user_name)
user && user.password_hash == Digest::MD5.hexdigest(password)
end
end
end
19. Zmiany w Rails 2.0 - abstrakcyjne formaty
# config/initializers/mime_types.rb
Mime.register_alias quot;text/htmlquot;, :iphone
class ApplicationController < ActionController::Base
before_filter :adjust_format_for_iphone
def adjust_format_for_iphone
user_agent = request.env[quot;HTTP_USER_AGENTquot;]
request.format = :iphone if user_agent && user_agent[/(iPhone|iPod)/]
end
end
class PostsController < ApplicationController
def index
respond_to do |format|
format.html # renders index.html.erb
format.iphone # renders index.iphone.erb
end
end
end
20. Zmiany w Rails 2.0 - filtry wykonujące się dla jednego typu
requestu
class FajnyKontroler < ApplicationController
before_filter do |c|
c.use_session_auth if c.request.format.html?
c.use_token_auth if c.request.format.xml?
end
sessions :off, :if => Proc.new { |request| request.format.iphone? }
end
# Btw, render i redirect w filtrach przerywają teraz wykonywanie akcji
21. Zmiany w Rails 2.0 - Lista rout w rake'u
# rake routes
from_subscriptions GET /subscriptions/from
{:action=>quot;fromquot;, :controller=>quot;subscriptionsquot;}
formatted_from_subscriptions GET /subscriptions/from.:format
{:action=>quot;fromquot;, :controller=>quot;subscriptionsquot;}
to_subscriptions GET /subscriptions/to
{:action=>quot;toquot;, :controller=>quot;subscriptionsquot;}
POST /subscriptions
{:action=>quot;createquot;, :controller=>quot;subscriptionsquot;}
PUT /subscriptions/:id
{:action=>quot;updatequot;, :controller=>quot;subscriptionsquot;}
22. Zmiany w Rails 2.0 - Odzielenie silinka renderującego od
formatu odpowiedzi
Akcja.format.renderer
Czym innym jest format, czym innym silnik który go wspiera
23. Zmiany w Rails 2.0 - Fikstury z odwołaniami po nazwie
# Kiedyś
subscription:
id: 17
tracking_user_id: 12
tracked_user_id: 13
transport_id: 4
created_at: 2007-10-06 10:00:00
# Teraz
subscription:
tracking_user: wiesio
tracked_user: henio
transport: jabber
created_at: 2007-10-06 10:00:00
# A także
assert_equal [updates(:foo), updates(:bar)], Update.find(:all)
assert_equal updates(:foo, :bar), Update.find(:all)
24. Zmiany w Rails 2.0 - Zabezpieczenia przed atakami CSRF
- Wytłumaczenie ataku
- Akcje wykonywane przy pomocy PUT, POST i DELETE nie wykonują się
jeśli formularz nie zawiera tokena unikalnego dla każdego
użytkownika
- Wszystkie Railsowe helpery jak form_for, link_to z ustawionym method
itp. domyślnie dodają kod wysyłający token
25. Zmiany w Rails 2.0 - Nowa składnia migracji
# Kiedyś
create_table :people do |t|
t.column, quot;account_idquot;, :integer
t.column, quot;first_namequot;, :string, :null => false
t.column, quot;last_namequot;, :string, :null => false
t.column, quot;descriptionquot;, :text
t.column, quot;created_atquot;, :datetime
t.column, quot;updated_atquot;, :datetime
end
# Teraz
create_table :people do |t|
t.integer :account_id
t.string :first_name, :last_name, :null => false
t.text :description
t.timestamps
end
26. Zmiany w Rails 2.0 - Sesje w cookies
- Sesje są teraz domyślnie trzymane po stronie klienta, w zaszyfrowanej
postaci, jako cookies
- Bardzo szybkie, w porządku przy umiarkowanym użyciu sesji
- Nie mogą zostać podmienione, ale mogą zostać podejrzane
- Limit 4k
27. Słowa Podsumowania
- Railsy nie są sukcesem czysto technologicznym...
- Są przedewszystkim pokazem tego, że aplikacje internetowe
można tworzyć inaczej - łatwiej, przyjemniej, bez ton XMLa,
a jednocześnie trzymając się utartych standardów i z zyskiem
je wykorzystując.
- Duży procent tej wizji przeniesiono do innych frameworków w
innych językach, co po części dowodzi, że quot;wizjaquot; ta jest
głównym quot;dziedzictwemquot; Railsów.
- Oczywiście nie przypadkiem Railsy powstały właśnie w Ruby - na
dziś dzień to w tym języku taką wizję możemy wyrazić najbardziej
naturalnie.
- Ale za 10 lat będziemy mieli lepszy język, a wizja popchnęła do
przodu całą dziedzinę.
- Dziękujemy za Rails!
28. Wykorzystane zasoby
- quot;Architectural Styles and the Design of Network-based Software
Architecturesquot;, Roy Fielding
http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
- quot;Architecture of the World Wide Web, Volume Onequot;
http://www.w3.org/TR/webarch/
- RFC 2616 quot;Hypertext Transfer Protocol -- HTTP/1.1quot;
http://www.ietf.org/rfc/rfc2616.txt
- RFC 2396 quot;Uniform Resource Identifiers (URI): Generic Syntaxquot;
http://www.ietf.org/rfc/rfc2396.txt
- Oficjalny anons Rails 2.0:
http://weblog.rubyonrails.org/2007/12/7/rails-2-0-it-s-done
- Opis zmian w Rails 2.0 na blogu quot;Ryan's Scrapsquot;
http://ryandaigle.com/articles/2007/12/7/rails-2-0-final-released-summary-of-features
- Railscasts, w szczególności ostatnie odcinki o Rails 2
http://railscasts.com/
- quot;Skinny controllers, fat modelsquot; - blog quot;the { buckblogs :here }quot;
http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model