Rest Ruby On Rails

2,851 views

Published on

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,851
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
22
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Rest Ruby On Rails

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

×