• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
ActiveResource & REST
 

ActiveResource & REST

on

  • 5,230 views

Matthijs Langenberg's slide's of his presentation at the RubyenRails 2007 conf in Amsterdam.

Matthijs Langenberg's slide's of his presentation at the RubyenRails 2007 conf in Amsterdam.

Statistics

Views

Total Views
5,230
Views on SlideShare
5,217
Embed Views
13

Actions

Likes
6
Downloads
236
Comments
0

1 Embed 13

http://2007.rubyenrails.nl 13

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    ActiveResource & REST ActiveResource & REST Presentation Transcript

    • REST & ActiveResource Matthijs Langenberg
    • Webservices
    • Wat zijn webservices
    • ”The W3C defines a Web Service as a software system designed to support interoperable machine to machine interaction over a network.” -- Wikipedia
    • Bevorder ‘machine to machine interaction’
    • HTML is moeilijk te parsen
    • Geef iets anders terug XML?
    • Just Another View
    • respond_to
    • class ArticlesController < ApplicationController def show @article = Article.find(params[:id]) respond_to do |format| format.html format.xml { render :xml => @article } end end end
    • Soorten Webservices • Remote procedure calls (RPC) • Service-oriented architecture (SOA) • Representational state transfer (REST)
    • Rails votes REST
    • Rails votes REST BIG TIME!
    • Wat is REST?
    • REpresentional State Transfer
    • HTTP’s: “convention over configuration”
    • Schreef geen vervanging voor iets wat HTTP je gratis geeft
    • HTTP Abuse Wat is er mis met dit request? GET http://myblog.com/articles/destroy/1
    • HTTP Abuse Wat is er mis met dit request? GET http://myblog.com/articles/destroy/1 Conflict
    • HTTP Abuse Wat is er mis met dit request? GET http://myblog.com/articles/destroy/1 Conflict • Actie staat in URL • Uitgevoerd actie is in conflict met HTTP methode
    • The REST-way DELETE http://myblog.com/articles/1
    • URI’s
    • URI’s GET /articles/create GET /articles/show/1 GET /articles/update/1 GET /articles/destroy/1
    • URI’s GET /articles/create GET /articles/show/1 GET /articles/update/1 GET /articles/destroy/1
    • Mapping
    • Mapping HTTP GET POST PUT DELETE
    • Mapping HTTP Controller GET SHOW POST CREATE PUT UPDATE DELETE DESTROY
    • Resourceful URI’s
    • Resourceful URI’s GET /articles POST /articles/create GET /articles/show/1 POST /articles/update/1 GET /articles/destroy/1
    • Resourceful URI’s ➡ GET /articles GET /articles ➡ POST /articles POST /articles/create ➡ GET /articles/1 GET /articles/show/1 ➡ PUT /articles/1 POST /articles/update/1 ➡ DELETE /articles/1 GET /articles/destroy/1
    • Gratis named routes
    • ActionController::Routing::Routes.draw do |map| map.resources :articles do |articles| articles.resources :comments end end
    • ActionController::Routing::Routes.draw do |map| map.resources :articles do |articles| articles.resources :comments end end
    • ActionController::Routing::Routes.draw do |map| map.resources :articles do |articles| articles.resources :comments end end articles_url article_url new_article_url edit_article_url article_comments_url article_comment_url article_new_comment_url article_edit_comment_url
    • ActionController::Routing::Routes.draw do |map| map.resources :articles do |articles| articles.resources :comments end end articles_url ➡ /articles article_url ➡ /articles/:id new_article_url ➡ /articles/new edit_article_url ➡ /articles/:id/edit article_comments_url ➡ /articles/:article_id/comments article_comment_url ➡ /articles/:article_id/comments/:id article_new_comment_url ➡ /articles/:article_id/comments/new article_edit_comment_url ➡ /articles/:article_id/comments/:id/edit
    • link_to article.title, { :controller => ‘article’, :action => ‘show’, :id => article }
    • link_to article.title, { :controller => ‘article’, :action => ‘show’, :id => article }
    • link_to article.title, { :controller => ‘article’, :action => ‘show’, :id => article } link_to article.title, article_url(article)
    • link_to article.title, { :controller => ‘article’, :action => ‘show’, :id => article } link_to article.title, article_url(article) link_to article.title, article
    • Wat zou je doen? Je wilt comments aan articles toevoegen, ArticlesController is aanwezig.
    • Wat zou je doen? Je wilt comments aan articles toevoegen, ArticlesController is aanwezig. 1) Voeg een actie ‘add_comment’ aan ArticlesController toe. (POST /articles/1/add_comment)
    • Wat zou je doen? Je wilt comments aan articles toevoegen, ArticlesController is aanwezig. 1) Voeg een actie ‘add_comment’ aan ArticlesController toe. (POST /articles/1/add_comment) 2) Maak een CommentsController, met een ‘create’ actie. (POST /comments/create?article_id=1)
    • Mr. RESTful zegt:
    • Mr. RESTful zegt: Antwoord 2
    • Mr. RESTful zegt: Antwoord 2 • Een comment is een een aparte resource
    • Mr. RESTful zegt: Antwoord 2 • Een comment is een een aparte resource • Er bestaat geen ‘add_comment’ methode in HTTP
    • Mr. RESTful zegt: Antwoord 2 • Een comment is een een aparte resource • Er bestaat geen ‘add_comment’ methode in HTTP • Er bestaat wel een ‘create’ (POST) methode in HTTP
    • Geen Namespaces! • POST /articles/create • POST /articles/create_comment • GET /articles/destroy • GET /articles/destroy_comment
    • Teveel vrijheid is niet goed
    • class ArticlesController < ApplicationController def show @article = Article.find(params[:id]) end def show_rss @article = Article.find(params[:id]) render :rss => @article.to_rss end def show_atom @article = Article.find(params[:id]) render :atom => @article.to_atom end def show_xml @article = Article.find(params[:id]) render :xml => @article.to_xml end def show_ajax @article = Article.find(params[:id]) render :template => show_article.rjs end end
    • Geen aparte actie voor alternatieve view!
    • class ArticlesController < ApplicationController def show @article = Article.find(params[:id]) respond_to do |format| format.html format.rss { render :rss => @article.to_rss } format.atom { render :atom => @article.to_atom } format.xml { render :xml => @article.to_xml } format.rjs { render :template => ‘show_article.rjs’ } end end end
    • Wauw! HTTP method naar controller actie mapping actie klinkt tof!
    • Maar er zit een adder ...
    • Maar er zit een adder ...
    • Browsers ondersteunen PUT en DELETE niet!
    • Browsers ondersteunen PUT en DELETE niet! <input name=quot;_methodquot; type=quot;hiddenquot; value=quot;putquot; />
    • Gelukkig zijn de helpers ook aangepast. ;-)
    • HTML_options • link_to “delete”, article_path(1), :method => ‘delete’ • link_to_remote, “delete”, article_path(1), :method => ‘delete’ • form_tag(member_path(2), :method => :put)
    • form_for remote_form_for Bepalen op basis van AR object de method: form_for(Movie.new): <form action=quot;/moviesquot; class=quot;new_moviequot; id=quot;new_moviequot; method=quot;postquot;> form_for(Movie.find(:first)): <form action=quot;/movies/1quot; class=quot;edit_moviequot; id=quot;edit_movie_1quot; method=quot;postquot;> <input name=quot;_methodquot; type=quot;hiddenquot; value=quot;putquot; />
    • Controller Acties
    • MoviesController#index
    • MoviesController#index # GET /movies # GET /movies.xml def index @movies = Movie.find(:all) respond_to do |format| format.html # index.html.erb format.xml { render :xml => @movies } end end
    • MoviesController#index <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> # GET /movies <movies> # GET /movies.xml <movie> def index <director>Chris Miller</director> @movies = Movie.find(:all) <id type=quot;integerquot;>1</id> <rating type=quot;decimalquot;>7.0</rating> respond_to do |format| <title>Shrek the Third</title> format.html # index.html.erb </movie> <movie> format.xml { render :xml => @movies } <director>Sam Raimi</director> end <id type=quot;integerquot;>2</id> end <rating type=quot;decimalquot;>6.9</rating> <title>Spider-Man 3</title> </movie> <movie> <director>Juan Carlos Fresnadillo</director> <id type=quot;integerquot;>3</id> <rating type=quot;decimalquot;>7.7</rating> <title>28 Weeks Later</title> </movie> </movies>
    • MoviesController#show
    • MoviesController#show # GET /movies/1 # GET /movies/1.xml def show @movie = Movie.find(params[:id]) respond_to do |format| format.html # show.html.erb format.xml { render :xml => @movie } end end
    • MoviesController#show # GET /movies/1 <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <movie> # GET /movies/1.xml <director>Chris Miller</director> def show <id type=quot;integerquot;>1</id> @movie = Movie.find(params[:id]) <rating type=quot;decimalquot;>7.0</rating> <title>Shrek the Third</title> respond_to do |format| </movie> format.html # show.html.erb format.xml { render :xml => @movie } end end
    • MoviesController#create
    • MoviesController#create # POST /movies # POST /movies.xml def create @movie = Movie.new(params[:movie]) respond_to do |format| if @movie.save flash[:notice] = 'Movie was successfully created.' format.html { redirect_to(@movie) } format.xml { render :xml => @movie, :status => :created, :location => @movie } else format.html { render :action => quot;newquot; } format.xml { render :xml => @movie.errors, :status => 422 } end end end
    • MoviesController#create Status: 201 Created Location: http://localhost:3000/movies/16 # POST /movies <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> # POST /movies.xml <movie> def create <director>Steven Spielbergh</director> @movie = Movie.new(params[:movie]) <id type=quot;integerquot;>15</id> <rating type=quot;decimalquot;>8.3</rating> respond_to do |format| <title>Letters from Iwo Jima</title> if @movie.save </movie> flash[:notice] = 'Movie was successfully created.' format.html { redirect_to(@movie) } format.xml { render :xml => @movie, :status => :created, :location => @movie } else format.html { render :action => quot;newquot; } format.xml { render :xml => @movie.errors, :status => 422 } end end end
    • MoviesController#create Status: 201 Created Location: http://localhost:3000/movies/16 # POST /movies <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> # POST /movies.xml <movie> def create <director>Steven Spielbergh</director> @movie = Movie.new(params[:movie]) <id type=quot;integerquot;>15</id> <rating type=quot;decimalquot;>8.3</rating> respond_to do |format| <title>Letters from Iwo Jima</title> if @movie.save </movie> flash[:notice] = 'Movie was successfully created.' format.html { redirect_to(@movie) } format.xml { render :xml => @movie, :status => :created, Status: 422 Unprocessable Entity :location => @movie } <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> else <errors> format.html { render :action => quot;newquot; } <error>Rating can't be blank</error> format.xml { render :xml => @movie.errors, :status => 422 } <error>Director can't be blank</error> end <error>Title can't be blank</error> end </errors> end
    • MoviesController#update
    • MoviesController#update # PUT /movies/1 # PUT /movies/1.xml def update @movie = Movie.find(params[:id]) respond_to do |format| if @movie.update_attributes(params[:movie]) flash[:notice] = 'Movie was successfully updated.' format.html { redirect_to(@movie) } format.xml { head :ok } else format.html { render :action => quot;editquot; } format.xml { render :xml => @movie.errors, :status => 422 } end end end
    • MoviesController#update Status: 200 OK # PUT /movies/1 # PUT /movies/1.xml def update @movie = Movie.find(params[:id]) respond_to do |format| if @movie.update_attributes(params[:movie]) flash[:notice] = 'Movie was successfully updated.' format.html { redirect_to(@movie) } format.xml { head :ok } else format.html { render :action => quot;editquot; } format.xml { render :xml => @movie.errors, :status => 422 } end end end
    • MoviesController#update Status: 200 OK # PUT /movies/1 # PUT /movies/1.xml def update @movie = Movie.find(params[:id]) Status: 422 Unprocessable Entity respond_to do |format| <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> if @movie.update_attributes(params[:movie]) <errors> flash[:notice] = 'Movie was successfully updated.' <error>Title can't be blank</error> format.html { redirect_to(@movie) } </errors> format.xml { head :ok } else format.html { render :action => quot;editquot; } format.xml { render :xml => @movie.errors, :status => 422 } end end end
    • MoviesController#destroy
    • MoviesController#destroy # DELETE /movies/1 # DELETE /movies/1.xml def destroy @movie = Movie.find(params[:id]) @movie.destroy respond_to do |format| format.html { redirect_to(movies_url) } format.xml { head :ok } end end
    • MoviesController#destroy # DELETE /movies/1 Status: 200 OK # DELETE /movies/1.xml def destroy @movie = Movie.find(params[:id]) @movie.destroy respond_to do |format| format.html { redirect_to(movies_url) } format.xml { head :ok } end end
    • Scaffolding
    • maar er is meer!
    • ActiveResource
    • ActiveResource • Object-oriented REST services • Transparent met een RESTful service (Rails) werken • Net als ActiveRecord, maar dan voor REST
    • Browser
    • Browser GET /movies.html Controller (RESTful)
    • Browser GET /movies.html Controller (RESTful) Movie.find(:all) ActiveRecord
    • Browser GET /movies.html Controller (RESTful) Movie.find(:all) ActiveRecord SELECT * FROM MOVIES DB
    • Browser Browser GET /movies.html Controller (RESTful) Movie.find(:all) ActiveRecord SELECT * FROM MOVIES DB
    • Browser Browser GET /movies.html GET /movies.html Controller Controller (RESTful) Movie.find(:all) ActiveRecord SELECT * FROM MOVIES DB
    • Browser Browser GET /movies.html GET /movies.html Controller Controller (RESTful) Movie.find(:all) Movie.find(:all) ActiveResource ActiveRecord SELECT * FROM MOVIES DB
    • Browser Browser GET /movies.html GET /movies.html Controller Controller (RESTful) Movie.find(:all) Movie.find(:all) GET /movies.xml ActiveResource ActiveRecord SELECT * FROM MOVIES DB
    • Configuratie
    • Werken met RESTful webservices (ActiveResource)
    • Create
    • Create
    • Read
    • Read
    • Update
    • Update
    • Destroy
    • Destroy
    • Wat doet ARes?
    • Wat doet ARes? • Genereer URL
    • Wat doet ARes? • Genereer URL • Request URL (XML)
    • Wat doet ARes? • Genereer URL • Request URL (XML) • Verwerk request (XML)
    • Wat doet ARes? • Genereer URL • Request URL (XML) • Verwerk request (XML) • Biedt ActiveRecord-like API
    • Demo
    • Demo 1) RESTful Rails applicatie (met curl)
    • Demo 1) RESTful Rails applicatie (met curl) 2) Rails applicatie met ActiveResource
    • Demo 1) RESTful Rails applicatie (met curl) 2) Rails applicatie met ActiveResource 3) ActiveResource gem
    • Vragen? <mlangenberg@gmail.com> #rubyenrails at irc.freenode.org