Author
shaokun
View
2.482
Download
23
Embed Size (px)
DESCRIPTION
关于 关于 Kude LabsKude Labs
• 博客 http://kudelabs.com
• 专注于 Web Applications– Schedule.ph– PRDGuide.com– FriendsMap.net
• Web Wednesday Web Wednesday 活动活动http://kudelabs.com/category/web-wednesday-guangzhou
R E S TR E S T
我将要分享的……我将要分享的……
1. REST—— 标准、架构或者理念?– Resource– CRUD– HTTP Verb
2. Ruby on Rails
3. RESTful Login & Search?
4. Twitter & Facebook API
5. Tips
6. Q & A
RESTREST
• ReRepresentational SState TTransfer
– Client-server
– Stateless 无状态
– Cacheable 可缓存
– Layered system 负载均衡、共享内存
– Code on Demand* 临时扩展客户端功能
– Uniform interface 简化、去耦
一种抽象的概念、架构蓝图一种抽象的概念、架构蓝图Just an Architecture, Not a Standard or ProtocolJust an Architecture, Not a Standard or Protocol
描述基于互联网的分布式系统描述基于互联网的分布式系统Describe Internet Based Remote SystemDescribe Internet Based Remote System
RRemote emote PProcedure rocedure CCallsalls
• 一种分布式函数调用接口
• 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 REST vsvs RPC RPC
• RPC– 允许定义任意的程序接口
• getUsers()
• getNewUsersSince(date)
• savePurchaseOrder()
• …
– 大多数通过 POST 进行通讯– 忽略 HTTP 现有功能
• Authentication
• Caching
• Content type
– SOAP 一种基于 HTTP 的通讯协议
• REST– 接口局限于现有的、标准的 H
TTP 操作• GET
• POST
• PUT
• DELETE
– 一种架构,而非协议– 充分利用 HTTP 协议– 交互的核心是 Stateful Resour
ces ,而非 Messages 或者 Operations
ResourceResourceCRUDCRUD
HTTP VerbHTTP Verb
ResourceResource
• Resouce 并不是数据• 而是数据 + 特定的表现形式 (representation)
– 所有事物都可以被抽象为 Resource – 每个 Resource 对应一个唯一的 URL – 通过 generic connector interface (HTTP) 进行操作– 对 Resource 的操作不会改变 URL– 所有的操作都是 Stateless
CRUD & HTTP VerbCRUD & HTTP Verb
• 对于 Resource 的操作 Create 、 Read 、 Update 和 Delete
• HTTP Verb– curl -X GET http://example.com/projects
– curl -X DELETE http://example.com/projects/1
HTTPHTTP CRUDCRUD SQLSQL
POST CREATE INSERT
GET READ SELECT
PUT UPDATE UPDATE
DELETE DELETE DELETE
REST Ruby on RailsREST Ruby on Rails
Ruby on RailsRuby on Rails
• 基于动态编程语言 Ruby
• MVC 架构 MModel-VView-CController
• 专注于 Web Application 的开发框架
• 从 v1.2.x 起支持 REST 架构
• v3 beta 可能在 1 月底发布!
REST Ruby on RailsREST Ruby on Rails
• 7 个 Controller 的 Action :– Index– Show– New– Edit– Create– Update– Destroy
• 4 个 HTTP Verb :– GET– POST– PUT– DELETE
HTTP VerbHTTP Verb URL with RESTURL with REST ActionAction URL without RESTURL without REST
GET /projects/1 show GET /projects/show/1
DELETE /projects/1 destroy GET /projects/destroy/1
PUT /projects/1 update POST /projects/update/1
POST /projects create POST /projects/create
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() endend
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; endend
User + Group = ?User + Group = ?
数据表结构
User 拥有很多 Groups
Group 拥有很多 Users
Users UsersGroups Groups1 N N 1
class Group < ActiveRecord::Base has_many :users_groups has_many :users, :through => :users_groupsend
class User < ActiveRecord::Base has_many :users_groups has_many :groups, :through => :users_groupsend
class UsersGroups < ActiveRecord::Base belongs_to :groups belongs_to :usersend
用例 Use CaseUser join Group
User leave Group
UsersControllerjoin_group()
# POST /users/1/join_group?group_id=2
leave_group()
# POST /users/1/leave_group?group_id=2
GroupsControlleradd_user()
# POST /groups/1/add_user?user_id=2
remove_user()
# POST /groups/1/remove_user?user_id=2
UserUser + + GroupGroup = = UserGroupUserGroup
MembershipMembership
class Group < ActiveRecord::Base has_many :memberships has_many :users, :through => :membershipsend
class User < ActiveRecord::Base has_many :memberships has_many :groups, :through => :membershipsend
class Membership < ActiveRecord::Base belongs_to :groups belongs_to :usersend
MembershipsControllercreate()# INSERT INTO "memberships" ("group_id", "user_id") VALUES(2, 1)
# POST /memberships?user_id=1&group_id=2
destroy()# DELETE FROM "memberships" WHERE "id" = 1
# DELETE /memberships/3
mine typesmine 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::ATO
M end end endend
• GET /users => HTML
• GET /users.xml => XML
• Accept: text/javascriptGET /users => json
• Accept: text/htmlGET /users.xml => XML
Nested ResrouceNested Resrouce
GET /groups
GET /groups/1
DELETE /groups/1
POST /groups
GET /users
GET /users/2
DELETE /users/2
POST /users
只是想对某个 只是想对某个 Group Group 中的 中的 Users 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 REST 世界中的 世界中的 Ajax Ajax 客户端客户端
• 通过 HTTP 来获取网络资源• 传输异步数据• 简单性• 可伸缩的架构
• 遵循 REST 架构“无状态服务器”的约束:– 服务器不关心客户端的状态– 客户端管理自己状态
RESTful Login & Search?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 endend
RESTful Search?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 APITwitter & Facebook API
Twitter APITwitter 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="array"> <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 VerbHTTP Verb URLURL
获取所有用户的 Statuses
GET http://twitter.com/statuses/public_timeline
获取特定用户的 Statuses
GET http://twitter.com/statues/user_timeline/userid.format
获取特定用户的某一个 Status
GET http://twitter.com/statues/show/statusid.format
创建一个新的 Status
POST http://twitter.com/statuses/update.format
删除一个 StatusDELETE/
POSThttp://twitter.com/statuses/destroy/statusid.format
GET /users/kudelabs/statuses.xmlGET /users/kudelabs/statuses.xml
GET /statuses/user_timeline/kudelabs.xmlGET /statuses/user_timeline/kudelabs.xml
完全的 完全的 RESTful Twitter APIRESTful Twitter API
操作操作 HTTP VerbHTTP Verb URLURL
获取所有用户的 Statuses GET /statuses.format
获取特定用户的 Statuses GET /users/{user_id}/statuses.format
获取特定用户的某一个 Status GET /users/{user_id}/statues/{status_id}.format
创建一个新的 Status POST /users/{user_id}/statuses.format
更新一个 Status PUT /users/{user_id}/statuses/{status_id}.format
删除一个 Status DELETE /users/{user_id}/statuses/{status_id}.format
Facebook APIFacebook 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?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 APIRPC API
• 唯一的入口http://api.facebook.com/restserver.php
• 严重依赖于 POST• 调用方法隐藏于参数中,例如 Users.getInfo• 自定义的、非 HTTP 的响应码
• 支持多种响应
T i p sT i p s
• 对新技术趋之若鹜
• 我创建的、愚蠢的 Resource:– Ownership– Membership– Nomination– Authorization
RESTful too MUCHRESTful 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_spammark_spam
并不是一个标准的 并不是一个标准的 ActionAction并不遵循 并不遵循 REST REST 架构架构
I am creating a SPAM resource!I am creating a SPAM resource!
POST /bookmarks/1/comments/2/spamPOST /bookmarks/1/comments/2/spam
map.resources map.resources :users:users do |users| do |users|
users.resources users.resources :bookmarks:bookmarks do |bookmarks| do |bookmarks|
bookmarks.resources bookmarks.resources :comments:comments do |comments| do |comments|
comments.resource comments.resource :spam:spam
endend
endend
endend
Your Your geniusgenius API for your team 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/spamsPOST /users/1/bookmarks/2/comments/3/spams
POST /comments/3/mark_spamPOST /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&POST /restserver.php?method=Users.getInfo& format=xml& format=xml& id=398382 id=398382
GET /users/398382.xmlGET /users/398382.xml
如果你还有兴趣……如果你还有兴趣……
http://media.rubyonrails.org/presentations/worldofresources.pdf
O’REILLY 出版的 RESTful Web Services
git clone http://github.com/shaokun/restgit clone http://github.com/shaokun/rest
或者来 或者来 Kude Labs Kude Labs 做客做客
Q & AQ & [email protected]@kudelabs.com