SlideShare a Scribd company logo
REST  &  R uby  o n  R ails 伍 少 坤 [email_address]
关于  Kude Labs 博客  http://kudelabs.com 专注于  Web Applications Schedule.ph PRDGuide.com FriendsMap.net Web Wednesday  活动 http://kudelabs.com/category/web-wednesday-guangzhou
R E S T
我将要分享的…… REST—— 标准、架构或者理念? Resource CRUD HTTP Verb Ruby on Rails RESTful Login & Search? Twitter & Facebook API Tips Q & A
REST Re presentational  S tate  T ransfer Client-server Stateless  无状态 Cacheable  可缓存 Layered system  负载均衡、共享内存 Code on Demand*  临时扩展客户端功能 Uniform interface  简化、去耦
一种抽象的概念、架构蓝图 Just an Architecture, Not a Standard or Protocol 描述基于互联网的分布式系统 Describe Internet Based Remote System
R emote  P rocedure  C alls 一种分布式函数调用接口 SOAP <?xml version=“1.0” encoding=“UTF-8”?> <soap:Envelope xmlns:soap=“http://schemas.xmlsoap.org/soap/envelope/”> <soap:Body> <gs:doGoogleSearch xmlns:gs=“urn:GoogleSearch”> <q>REST</q> </gs:doGoogleSearch> </soap:Body> </soap:Envelope> Facebook API 、  Flickr API 、淘宝  API http://api.flickr.com/services/rest/?method= flickr.photos.search http://gw.api.tbsandbox.com/router/rest?method= taobao.taobaoke.items.get
REST  vs  RPC RPC 允许定义任意的程序接口 getUsers() getNewUsersSince(date) savePurchaseOrder() … 大多数通过  POST  进行通讯 忽略  HTTP  现有功能 Authentication Caching Content type SOAP  一种基于  HTTP  的通讯协议 REST 接口局限于现有的、标准的  HTTP  操作 GET POST PUT DELETE 一种架构,而非协议 充分利用  HTTP  协议 交互的核心是  Stateful Resources ,而非  Messages  或者  Operations
Resource CRUD HTTP Verb
Resource Resouce  并不是数据 而是数据 + 特定的表现形式  (representation) 所有事物都可以被抽象为  Resource  每个  Resource  对应一个唯一的  URL  通过  generic connector interface (HTTP)  进行操作 对  Resource  的操作不会改变  URL 所有的操作都是  Stateless
CRUD & HTTP Verb 对于  Resource  的操作  C reate 、 R ead 、 U pdate  和  D elete HTTP Verb curl -X GET http://example.com/projects curl -X DELETE http://example.com/projects/1 SQL CRUD HTTP DELETE DELETE DELETE UPDATE UPDATE PUT SELECT READ GET INSERT CREATE POST
REST Ruby on Rails
Ruby on Rails 基于动态编程语言  Ruby MVC  架构  M odel- V iew- C ontroller 专注于  Web Application  的开发框架 从 v1.2.x 起支持  REST  架构 v3 beta  可能在 1 月底发布!
REST Ruby on Rails 7 个  Controller  的  Action : Index Show New Edit Create Update Destroy 4  个  HTTP Verb : GET POST PUT DELETE
POST /projects/create create /projects POST POST /projects/update/1 update /projects/1 PUT GET /projects/destroy/1 destroy /projects/1 DELETE GET /projects/show/1 show /projects/1 GET URL without REST Action URL with REST HTTP Verb
class  UsersController  <  ApplicationController # GET /users/1 def  show() end # POST /users def  create() end # PUT /users/1 def  update() end # DELETE /users/1 def  destroy() end end
class  UsersController  <  ApplicationController # GET /users/new def  new ; end # GET /users/1/edit def  edit ; end # GET /users def  index ; end # GET /users/1 def  show ; end # POST /users def  create ; end # PUT /users/1 def  update ; end # DELETE /users/1 def  destroy ; end end
User + Group = ?
数据表结构 User  拥有很多  Groups Group  拥有很多  Users Users UsersGroups Groups 1 N N 1
class  Group  <  ActiveRecord::Base has_many  :users_groups has_many  :users , :through =>  :users_groups end class  User  <  ActiveRecord::Base has_many  :users_groups has_many  :groups , :through =>  :users_groups end class  UsersGroups  <  ActiveRecord::Base belongs_to  :groups belongs_to  :users end
用例  Use Case User join Group User leave Group
UsersController join_group() # POST /users/1/join_group?group_id=2 leave_group() # POST /users/1/leave_group?group_id=2 GroupsController add_user() # POST /groups/1/add_user?user_id=2 remove_user() # POST /groups/1/remove_user?user_id=2 
User  +  Group  =  UserGroup Membership
class Group < ActiveRecord::Base has_many  :memberships has_many :users, :through =>  :memberships end class User < ActiveRecord::Base has_many  :memberships has_many :groups, :through =>  :memberships end class  Membership  < ActiveRecord::Base belongs_to :groups belongs_to :users end
MembershipsController create() # INSERT INTO &quot;memberships&quot; (&quot;group_id&quot;, &quot;user_id&quot;) VALUES(2, 1) # POST /memberships?user_id=1&group_id=2 destroy() # DELETE FROM &quot;memberships&quot; WHERE &quot;id&quot; = 1 # DELETE /memberships/3 
mine types class  UsersController  <  ApplicationController # GET /users # GET /users.xml def  index @users = User.all respond_to do |format| format.html # index.html.erb format.js  { render :json => @users } format.xml  { render :xml => @users } fomrat.atom do render :action => “atom”, :content_type => Mine::ATOM end end end end
GET /users  => HTML GET /users.xml  => XML Accept: text/javascript GET /users  => json Accept: text/html GET /users.xml  => XML
Nested Resrouce GET  /groups GET  /groups/1 DELETE /groups/1 POST  /groups GET  /users GET  /users/2 DELETE /users/2 POST  /users 只是想对某个  Group  中的  Users  进行操作呢?
map.resources  :groups  do |groups| groups.resources  :users end GET  /groups/1/users GET  /groups/1/users/2 DELETE /groups/1/users/2 POST  /groups/1/users
REST  世界中的  Ajax  客户端
通过  HTTP  来获取网络资源 传输异步数据 简单性 可伸缩的架构 遵循  REST  架构“无状态服务器”的约束: 服务器不关心客户端的状态 客户端管理自己状态
RESTful Login & Search?
你如何实现  Login ? POST /login?user=shaokun&password=*** POST /signin?user=shaokun&password=*** https://reg.163.com/logins.jsp http://ptlogin2.qq.com/login
Login  的  Resource  是什么? Login  的  HTTP Verb  是什么? Login  的  Controller Action  是什么?
class  SessionsController  <  ApplicationController # GET /sessions def  new end # POST /sessions def  create end # DELETE /sessions # logout   def  destroy end end
RESTful Search? http://www.google.com/search?q=rest http://www.baidu.com/s?wd=rest
class SearchController < ApplicationController # GET /search def new end # POST /search def create end end
“ 天才”般简单地颠覆了  Google  和  Baidu ? 但是…… 构造了一个更复杂的操作 无法简单的返回缓存结果 无法复制搜索结果的  URL REST  错了吗?我们错了吗?
http://www.google.com/search?q=REST HTTP Verb  是  GET scope  是 “ /search?q=REST” http://www.google.com/search?q=ruby scope  是 “ /search?q=ruby” http://www.google.com/ scope  是 “ /”
Twitter & Facebook API
Twitter API 基于  Ruby on Rails 比较遵循  REST  架构 支持多用响应格式,例如  xml , json , rss , atom  等 简单学、简单用
浏览器中 http://twitter.com/statuses/user_timeline/kudelabs.xml 命令行中 curl -X GET http://twitter.com/statuses/public_timeline curl –X GET http://twitter.com/statuses/user_timeline/kudelabs.xml curl  更新  Kude Labs  的  Twitter
<statuses type=&quot;array&quot;> <status> <created_at>Wed Feb 25 07:45:57 +0000 2009</created_at> <id>1248444034</id> <text>What to eat tonight?</text> <source>web</source> <truncated>false</truncated> <in_reply_to_status_id/> <in_reply_to_user_id/> <favorited>false</favorited> <in_reply_to_screen_name/> </status> </statuses>
http://twitter.com/statuses/destroy/statusid.format DELETE/ POST 删除一个  Status http://twitter.com/statuses/update.format POST 创建一个新的  Status http://twitter.com/statues/show/statusid.format GET 获取特定用户的某一个  Status http://twitter.com/statues/user_timeline/userid.format GET 获取特定用户的  Statuses http://twitter.com/statuses/public_timeline GET 获取所有用户的  Statuses URL HTTP Verb 操作
GET /users/kudelabs/statuses.xml GET /statuses/user_timeline/kudelabs.xml
完全的  RESTful Twitter API /users/{user_id}/statuses/{status_id}.format PUT 更新一个  Status /users/{user_id}/statuses/{status_id}.format DELETE 删除一个  Status /users/{user_id}/statuses.format POST 创建一个新的  Status /users/{user_id}/statues/{status_id}.format GET 获取特定用户的某一个  Status /users/{user_id}/statuses.format GET 获取特定用户的  Statuses /statuses.format GET 获取所有用户的  Statuses URL HTTP Verb 操作
Facebook API Facebook  是怎么描述它的  API  的: The API uses a REST-like interface.  This means that our Facebook method calls are made over the internet by sending HTTP GET or POST requests to the Facebook API REST server (http://api.facebook.com/restserver.php). Nearly any computer language can be used to communicate over HTTP with the REST server.
RESTful API? Users.getInfo Parameters: Required api_key, call_id, sig, v, uids, fields Optional session_key, format, callback Error Codes: 1, 2, 5, 100, 101, 102, 103, 104, 601
只是一种  RPC API 唯一的入口 http://api.facebook.com/restserver.php 严重依赖于  POST 调用方法隐藏于参数中,例如  Users.getInfo 自定义的、非  HTTP  的响应码 支持多种响应
T i p s
对新技术趋之若鹜 我创建的、愚蠢的  Resource: Ownership Membership Nomination Authorization
RESTful too MUCH
User A  创建  Bookmark A # POST /bookmarks User X  评论  Bookmark A # POST /bookmarks/1/comments User A  将某一个评论标为  Spam # PUT /bookmarks/1/comments/2/mark_spam
mark_spam 并不是一个标准的  Action 并不遵循  REST  架构
I am creating a SPAM resource! POST /bookmarks/1/comments/2/spam 
map.resources  :users  do |users| users.resources  :bookmarks  do |bookmarks| bookmarks.resources  :comments  do |comments| comments.resource  :spam end end end 
Your  genius  API for your team GET /users/1/bookmarks/2/comments GET /users/1/bookmarks/2/comments/3 POST /users/1/bookmarks/2/comments POST /users/1/bookmarks/2/comments/3/spams   
POST /users/1/bookmarks/2/comments/3/spams POST /comments/3/mark_spam   
是否容易被团队成员接受? Accept by your team 是否存在于团队常用用例中的词汇? Common vocabulary 是否有助于将其开放为  API ? Help expose as a API 是否为开发人员建立更简单的、可遵循的规则? Simple rules, could be followed by your team 与现存的、有用的插件是否兼容? Work with the existing great plugin
POST /restserver.php?method=Users.getInfo&   format=xml&   id=398382 GET /users/398382.xml
如果你还有兴趣……
http://media.rubyonrails.org/presentations/worldofresources.pdf
O’REILLY  出版的  RESTful Web Services
git clone http://github.com/shaokun/rest
或者来  Kude Labs  做客
Q & A [email_address]
Ad

Recommended

Puppet安装测试
Puppet安装测试
Yiwei Ma
 
Spring 2.0 技術手冊第九章 - API 封裝
Spring 2.0 技術手冊第九章 - API 封裝
Justin Lin
 
Jsp
Jsp
rdandy
 
Spring 2.0 技術手冊第八章 - View 層方案、Web 框架整合
Spring 2.0 技術手冊第八章 - View 層方案、Web 框架整合
Justin Lin
 
Spring 2.0 技術手冊第五章 - JDBC、交易支援
Spring 2.0 技術手冊第五章 - JDBC、交易支援
Justin Lin
 
用JAX-RS和Jersey完成RESTful Web Services
用JAX-RS和Jersey完成RESTful Web Services
javatwo2011
 
Spring 2.0 技術手冊第十章 - 專案:線上書籤
Spring 2.0 技術手冊第十章 - 專案:線上書籤
Justin Lin
 
Spring 2.0 技術手冊第七章 - Spring Web MVC 框架
Spring 2.0 技術手冊第七章 - Spring Web MVC 框架
Justin Lin
 
VIM for the PHP Developer
VIM for the PHP Developer
John Congdon
 
Rails web api 开发
Rails web api 开发
shaokun
 
Git flow
Git flow
shaokun
 
iOS 图片浏览器 DIY
iOS 图片浏览器 DIY
shaokun
 
More to RoC weibo
More to RoC weibo
shaokun
 
WebSocket 实时推特流
WebSocket 实时推特流
shaokun
 
Rack
Rack
shaokun
 
Rails Engine | Modular application
Rails Engine | Modular application
mirrec
 
Namespace less engine
Namespace less engine
shaokun
 
API Survey #2 - Firebase realtime database
API Survey #2 - Firebase realtime database
Szuping Wang
 
開放原始碼 Ch2.5 app - oss - 3rd party api(ver 1.0)
開放原始碼 Ch2.5 app - oss - 3rd party api(ver 1.0)
My own sweet home!
 
Ajax Transportation Methods
Ajax Transportation Methods
yiditushe
 
Erlang Practice
Erlang Practice
litaocheng
 
互联网创业服务器运维工具集
互联网创业服务器运维工具集
zhen chen
 
Struts Mitac(1)
Struts Mitac(1)
wangjiaz
 
Asp.net mvc 培训
Asp.net mvc 培训
lotusprince
 
RESTful
RESTful
PingLun Liao
 
CRUD 綜合運用
CRUD 綜合運用
Shengyou Fan
 
Ria的强力后盾:rest+海量存储
Ria的强力后盾:rest+海量存储
zhen chen
 
PHP Coding Standard and 50+ Programming Skills
PHP Coding Standard and 50+ Programming Skills
Ho Kim
 
使用 Kong 與 GitOps 來管理您企業的 API 呼叫 @ 2024 台灣雲端大會
使用 Kong 與 GitOps 來管理您企業的 API 呼叫 @ 2024 台灣雲端大會
Johnny Sung
 
使用 Controller
使用 Controller
Shengyou Fan
 

More Related Content

Viewers also liked (9)

VIM for the PHP Developer
VIM for the PHP Developer
John Congdon
 
Rails web api 开发
Rails web api 开发
shaokun
 
Git flow
Git flow
shaokun
 
iOS 图片浏览器 DIY
iOS 图片浏览器 DIY
shaokun
 
More to RoC weibo
More to RoC weibo
shaokun
 
WebSocket 实时推特流
WebSocket 实时推特流
shaokun
 
Rack
Rack
shaokun
 
Rails Engine | Modular application
Rails Engine | Modular application
mirrec
 
Namespace less engine
Namespace less engine
shaokun
 
VIM for the PHP Developer
VIM for the PHP Developer
John Congdon
 
Rails web api 开发
Rails web api 开发
shaokun
 
Git flow
Git flow
shaokun
 
iOS 图片浏览器 DIY
iOS 图片浏览器 DIY
shaokun
 
More to RoC weibo
More to RoC weibo
shaokun
 
WebSocket 实时推特流
WebSocket 实时推特流
shaokun
 
Rails Engine | Modular application
Rails Engine | Modular application
mirrec
 
Namespace less engine
Namespace less engine
shaokun
 

Similar to Rest Ruby On Rails (20)

API Survey #2 - Firebase realtime database
API Survey #2 - Firebase realtime database
Szuping Wang
 
開放原始碼 Ch2.5 app - oss - 3rd party api(ver 1.0)
開放原始碼 Ch2.5 app - oss - 3rd party api(ver 1.0)
My own sweet home!
 
Ajax Transportation Methods
Ajax Transportation Methods
yiditushe
 
Erlang Practice
Erlang Practice
litaocheng
 
互联网创业服务器运维工具集
互联网创业服务器运维工具集
zhen chen
 
Struts Mitac(1)
Struts Mitac(1)
wangjiaz
 
Asp.net mvc 培训
Asp.net mvc 培训
lotusprince
 
RESTful
RESTful
PingLun Liao
 
CRUD 綜合運用
CRUD 綜合運用
Shengyou Fan
 
Ria的强力后盾:rest+海量存储
Ria的强力后盾:rest+海量存储
zhen chen
 
PHP Coding Standard and 50+ Programming Skills
PHP Coding Standard and 50+ Programming Skills
Ho Kim
 
使用 Kong 與 GitOps 來管理您企業的 API 呼叫 @ 2024 台灣雲端大會
使用 Kong 與 GitOps 來管理您企業的 API 呼叫 @ 2024 台灣雲端大會
Johnny Sung
 
使用 Controller
使用 Controller
Shengyou Fan
 
Jetty服务器架构及调优.v2 2011-5
Jetty服务器架构及调优.v2 2011-5
lovingprince58
 
Ruby rails分享
Ruby rails分享
Cam Song
 
Intro to REST
Intro to REST
Leon Gao(高磊)
 
Intro to rest
Intro to rest
Leon Gao(高磊)
 
使用 Controller
使用 Controller
Shengyou Fan
 
Struts快速学习指南
Struts快速学习指南
yiditushe
 
Jsp讲义
Jsp讲义
yiditushe
 
API Survey #2 - Firebase realtime database
API Survey #2 - Firebase realtime database
Szuping Wang
 
開放原始碼 Ch2.5 app - oss - 3rd party api(ver 1.0)
開放原始碼 Ch2.5 app - oss - 3rd party api(ver 1.0)
My own sweet home!
 
Ajax Transportation Methods
Ajax Transportation Methods
yiditushe
 
Erlang Practice
Erlang Practice
litaocheng
 
互联网创业服务器运维工具集
互联网创业服务器运维工具集
zhen chen
 
Struts Mitac(1)
Struts Mitac(1)
wangjiaz
 
Asp.net mvc 培训
Asp.net mvc 培训
lotusprince
 
Ria的强力后盾:rest+海量存储
Ria的强力后盾:rest+海量存储
zhen chen
 
PHP Coding Standard and 50+ Programming Skills
PHP Coding Standard and 50+ Programming Skills
Ho Kim
 
使用 Kong 與 GitOps 來管理您企業的 API 呼叫 @ 2024 台灣雲端大會
使用 Kong 與 GitOps 來管理您企業的 API 呼叫 @ 2024 台灣雲端大會
Johnny Sung
 
Jetty服务器架构及调优.v2 2011-5
Jetty服务器架构及调优.v2 2011-5
lovingprince58
 
Ruby rails分享
Ruby rails分享
Cam Song
 
Struts快速学习指南
Struts快速学习指南
yiditushe
 
Ad

Rest Ruby On Rails

  • 1. REST & R uby o n R ails 伍 少 坤 [email_address]
  • 2. 关于 Kude Labs 博客 http://kudelabs.com 专注于 Web Applications Schedule.ph PRDGuide.com FriendsMap.net Web Wednesday 活动 http://kudelabs.com/category/web-wednesday-guangzhou
  • 3. R E S T
  • 4. 我将要分享的…… REST—— 标准、架构或者理念? Resource CRUD HTTP Verb Ruby on Rails RESTful Login & Search? Twitter & Facebook API Tips Q & A
  • 5. REST Re presentational S tate T ransfer Client-server Stateless 无状态 Cacheable 可缓存 Layered system 负载均衡、共享内存 Code on Demand* 临时扩展客户端功能 Uniform interface 简化、去耦
  • 6. 一种抽象的概念、架构蓝图 Just an Architecture, Not a Standard or Protocol 描述基于互联网的分布式系统 Describe Internet Based Remote System
  • 7. R emote P rocedure C alls 一种分布式函数调用接口 SOAP <?xml version=“1.0” encoding=“UTF-8”?> <soap:Envelope xmlns:soap=“http://schemas.xmlsoap.org/soap/envelope/”> <soap:Body> <gs:doGoogleSearch xmlns:gs=“urn:GoogleSearch”> <q>REST</q> </gs:doGoogleSearch> </soap:Body> </soap:Envelope> Facebook API 、 Flickr API 、淘宝 API http://api.flickr.com/services/rest/?method= flickr.photos.search http://gw.api.tbsandbox.com/router/rest?method= taobao.taobaoke.items.get
  • 8. REST vs RPC RPC 允许定义任意的程序接口 getUsers() getNewUsersSince(date) savePurchaseOrder() … 大多数通过 POST 进行通讯 忽略 HTTP 现有功能 Authentication Caching Content type SOAP 一种基于 HTTP 的通讯协议 REST 接口局限于现有的、标准的 HTTP 操作 GET POST PUT DELETE 一种架构,而非协议 充分利用 HTTP 协议 交互的核心是 Stateful Resources ,而非 Messages 或者 Operations
  • 10. Resource Resouce 并不是数据 而是数据 + 特定的表现形式 (representation) 所有事物都可以被抽象为 Resource 每个 Resource 对应一个唯一的 URL 通过 generic connector interface (HTTP) 进行操作 对 Resource 的操作不会改变 URL 所有的操作都是 Stateless
  • 11. CRUD & HTTP Verb 对于 Resource 的操作 C reate 、 R ead 、 U pdate 和 D elete HTTP Verb curl -X GET http://example.com/projects curl -X DELETE http://example.com/projects/1 SQL CRUD HTTP DELETE DELETE DELETE UPDATE UPDATE PUT SELECT READ GET INSERT CREATE POST
  • 12. REST Ruby on Rails
  • 13. Ruby on Rails 基于动态编程语言 Ruby MVC 架构 M odel- V iew- C ontroller 专注于 Web Application 的开发框架 从 v1.2.x 起支持 REST 架构 v3 beta 可能在 1 月底发布!
  • 14. REST Ruby on Rails 7 个 Controller 的 Action : Index Show New Edit Create Update Destroy 4 个 HTTP Verb : GET POST PUT DELETE
  • 15. POST /projects/create create /projects POST POST /projects/update/1 update /projects/1 PUT GET /projects/destroy/1 destroy /projects/1 DELETE GET /projects/show/1 show /projects/1 GET URL without REST Action URL with REST HTTP Verb
  • 16. class UsersController < ApplicationController # GET /users/1 def show() end # POST /users def create() end # PUT /users/1 def update() end # DELETE /users/1 def destroy() end end
  • 17. class UsersController < ApplicationController # GET /users/new def new ; end # GET /users/1/edit def edit ; end # GET /users def index ; end # GET /users/1 def show ; end # POST /users def create ; end # PUT /users/1 def update ; end # DELETE /users/1 def destroy ; end end
  • 19. 数据表结构 User 拥有很多 Groups Group 拥有很多 Users Users UsersGroups Groups 1 N N 1
  • 20. class Group < ActiveRecord::Base has_many :users_groups has_many :users , :through => :users_groups end class User < ActiveRecord::Base has_many :users_groups has_many :groups , :through => :users_groups end class UsersGroups < ActiveRecord::Base belongs_to :groups belongs_to :users end
  • 21. 用例 Use Case User join Group User leave Group
  • 22. UsersController join_group() # POST /users/1/join_group?group_id=2 leave_group() # POST /users/1/leave_group?group_id=2 GroupsController add_user() # POST /groups/1/add_user?user_id=2 remove_user() # POST /groups/1/remove_user?user_id=2 
  • 23. User + Group = UserGroup Membership
  • 24. class Group < ActiveRecord::Base has_many :memberships has_many :users, :through => :memberships end class User < ActiveRecord::Base has_many :memberships has_many :groups, :through => :memberships end class Membership < ActiveRecord::Base belongs_to :groups belongs_to :users end
  • 25. MembershipsController create() # INSERT INTO &quot;memberships&quot; (&quot;group_id&quot;, &quot;user_id&quot;) VALUES(2, 1) # POST /memberships?user_id=1&group_id=2 destroy() # DELETE FROM &quot;memberships&quot; WHERE &quot;id&quot; = 1 # DELETE /memberships/3 
  • 26. mine types class UsersController < ApplicationController # GET /users # GET /users.xml def index @users = User.all respond_to do |format| format.html # index.html.erb format.js { render :json => @users } format.xml { render :xml => @users } fomrat.atom do render :action => “atom”, :content_type => Mine::ATOM end end end end
  • 27. GET /users => HTML GET /users.xml => XML Accept: text/javascript GET /users => json Accept: text/html GET /users.xml => XML
  • 28. Nested Resrouce GET /groups GET /groups/1 DELETE /groups/1 POST /groups GET /users GET /users/2 DELETE /users/2 POST /users 只是想对某个 Group 中的 Users 进行操作呢?
  • 29. map.resources :groups do |groups| groups.resources :users end GET /groups/1/users GET /groups/1/users/2 DELETE /groups/1/users/2 POST /groups/1/users
  • 30. REST 世界中的 Ajax 客户端
  • 31. 通过 HTTP 来获取网络资源 传输异步数据 简单性 可伸缩的架构 遵循 REST 架构“无状态服务器”的约束: 服务器不关心客户端的状态 客户端管理自己状态
  • 32. RESTful Login & Search?
  • 33. 你如何实现 Login ? POST /login?user=shaokun&password=*** POST /signin?user=shaokun&password=*** https://reg.163.com/logins.jsp http://ptlogin2.qq.com/login
  • 34. Login 的 Resource 是什么? Login 的 HTTP Verb 是什么? Login 的 Controller Action 是什么?
  • 35. class SessionsController < ApplicationController # GET /sessions def new end # POST /sessions def create end # DELETE /sessions # logout  def destroy end end
  • 36. RESTful Search? http://www.google.com/search?q=rest http://www.baidu.com/s?wd=rest
  • 37. class SearchController < ApplicationController # GET /search def new end # POST /search def create end end
  • 38. “ 天才”般简单地颠覆了 Google 和 Baidu ? 但是…… 构造了一个更复杂的操作 无法简单的返回缓存结果 无法复制搜索结果的 URL REST 错了吗?我们错了吗?
  • 39. http://www.google.com/search?q=REST HTTP Verb 是 GET scope 是 “ /search?q=REST” http://www.google.com/search?q=ruby scope 是 “ /search?q=ruby” http://www.google.com/ scope 是 “ /”
  • 41. Twitter API 基于 Ruby on Rails 比较遵循 REST 架构 支持多用响应格式,例如 xml , json , rss , atom 等 简单学、简单用
  • 42. 浏览器中 http://twitter.com/statuses/user_timeline/kudelabs.xml 命令行中 curl -X GET http://twitter.com/statuses/public_timeline curl –X GET http://twitter.com/statuses/user_timeline/kudelabs.xml curl 更新 Kude Labs 的 Twitter
  • 43. <statuses type=&quot;array&quot;> <status> <created_at>Wed Feb 25 07:45:57 +0000 2009</created_at> <id>1248444034</id> <text>What to eat tonight?</text> <source>web</source> <truncated>false</truncated> <in_reply_to_status_id/> <in_reply_to_user_id/> <favorited>false</favorited> <in_reply_to_screen_name/> </status> </statuses>
  • 44. http://twitter.com/statuses/destroy/statusid.format DELETE/ POST 删除一个 Status http://twitter.com/statuses/update.format POST 创建一个新的 Status http://twitter.com/statues/show/statusid.format GET 获取特定用户的某一个 Status http://twitter.com/statues/user_timeline/userid.format GET 获取特定用户的 Statuses http://twitter.com/statuses/public_timeline GET 获取所有用户的 Statuses URL HTTP Verb 操作
  • 45. GET /users/kudelabs/statuses.xml GET /statuses/user_timeline/kudelabs.xml
  • 46. 完全的 RESTful Twitter API /users/{user_id}/statuses/{status_id}.format PUT 更新一个 Status /users/{user_id}/statuses/{status_id}.format DELETE 删除一个 Status /users/{user_id}/statuses.format POST 创建一个新的 Status /users/{user_id}/statues/{status_id}.format GET 获取特定用户的某一个 Status /users/{user_id}/statuses.format GET 获取特定用户的 Statuses /statuses.format GET 获取所有用户的 Statuses URL HTTP Verb 操作
  • 47. Facebook API Facebook 是怎么描述它的 API 的: The API uses a REST-like interface. This means that our Facebook method calls are made over the internet by sending HTTP GET or POST requests to the Facebook API REST server (http://api.facebook.com/restserver.php). Nearly any computer language can be used to communicate over HTTP with the REST server.
  • 48. RESTful API? Users.getInfo Parameters: Required api_key, call_id, sig, v, uids, fields Optional session_key, format, callback Error Codes: 1, 2, 5, 100, 101, 102, 103, 104, 601
  • 49. 只是一种 RPC API 唯一的入口 http://api.facebook.com/restserver.php 严重依赖于 POST 调用方法隐藏于参数中,例如 Users.getInfo 自定义的、非 HTTP 的响应码 支持多种响应
  • 50. T i p s
  • 51. 对新技术趋之若鹜 我创建的、愚蠢的 Resource: Ownership Membership Nomination Authorization
  • 53. User A 创建 Bookmark A # POST /bookmarks User X 评论 Bookmark A # POST /bookmarks/1/comments User A 将某一个评论标为 Spam # PUT /bookmarks/1/comments/2/mark_spam
  • 54. mark_spam 并不是一个标准的 Action 并不遵循 REST 架构
  • 55. I am creating a SPAM resource! POST /bookmarks/1/comments/2/spam 
  • 56. map.resources :users do |users| users.resources :bookmarks do |bookmarks| bookmarks.resources :comments do |comments| comments.resource :spam end end end 
  • 57. Your genius API for your team GET /users/1/bookmarks/2/comments GET /users/1/bookmarks/2/comments/3 POST /users/1/bookmarks/2/comments POST /users/1/bookmarks/2/comments/3/spams   
  • 58. POST /users/1/bookmarks/2/comments/3/spams POST /comments/3/mark_spam   
  • 59. 是否容易被团队成员接受? Accept by your team 是否存在于团队常用用例中的词汇? Common vocabulary 是否有助于将其开放为 API ? Help expose as a API 是否为开发人员建立更简单的、可遵循的规则? Simple rules, could be followed by your team 与现存的、有用的插件是否兼容? Work with the existing great plugin
  • 60. POST /restserver.php?method=Users.getInfo& format=xml& id=398382 GET /users/398382.xml
  • 63. O’REILLY 出版的 RESTful Web Services
  • 65. 或者来 Kude Labs 做客
  • 66. Q & A [email_address]