RESTful架构,一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,因此正获得愈来愈多网站的采用java
起源 REST这个词,是Roy Thomas Fielding在他2000年的博士论文中提出的git
Fielding将他对互联网软件的架构原则,定名为REST,即Representational State Transfer的缩写。这个词组的翻译是"表现层状态转化",若是一个架构符合rest原则,咱们就称它为restful架构github
资源(resources)json
rest翻译为表现层状态转化,它没有指名是谁的表现层,缺少主语,在这里,咱们用资源当作主语,即为资源的表现层状态转化。api
所谓资源,就是网络上的一个实体,它能够是一张图片,一段文本。。。咱们能够用一个url指向它,用户经过url就能访问到这个资源。数组
普及两个概念 uri与url,uri(统一资源标识符 Uniform Resource Identifier),url(统一资源定位符 Uniform Resource Locator),其中url是uri的子集服务器
表现层(representation)restful
资源是一种信息实体,它能够有多种外在表现,好比文本能够以txt格式表现,也能够用html,json,xml格式表现,咱们把资源具体呈现出的形式叫作它的表现层。网络
uri指向资源,但不表明资源的形式,http头部中的accept和content-type等表达了资源的形式
状态转化(state transfer)
访问一个uri,就表明客户和服务器发生了一个交互,这个过程会涉及到数据和状态的变化。
互联网通讯协议http协议,是无状态的,不能记录资源的各类状态,资源的状态保存在服务器端,若是要操做服务器上的资源,就要经过一些手段,让服务器知道,从而让服务器的资源发生状态转化,这个变化是创建在表现层之上的,就是表现层状态转化。
客户端使用的手段,只能是http协议,http协议里有不少操做方式的动词好比get,post,put,delete,它们对应了四种基本操做,get用来获取资源(查),post用来新建资源(增)或者修改资源(改),put用来更新资源(改),delete用来删除资源(删)。
综上
restfull架构即为
每一个url指向一种资源,客户端和服务器之间传递资源的某种表现层,客户经过4个http动词,对服务器资源进行操做,实现服务器资源表现层状态转化
常见误区
url中含有动词,好比/users/update/1,其中update是动词(手段),这个url就不知足restful架构,正确的写法是/user/1,而后用put方式或post方式
url中带有版本号,不一样版本,能够理解为同一资源的不一样表现形式,能够把版本号放到http头信息中,从url剔除
restful api设计
1、协议
api与用户的通讯协议采用http协议
2、域名
尽可能将api部署到专用域名下,好比 http://api.test.com。若是api很少且比较简单,不太会进一步扩展,也能够放到主域名下,好比http://test.com/api/...
3、版本(version)
将版本号放到http头信息中,也有说法说版本号放到url中更方便直接,github的是放在http头信息里的
4、路径(endpoint)
路径又称“终点”(endpoint),表示api具体网址,在restful架构中,每一个网址表明一种资源(resource),因此网址中不能有动词,好比说一个api提供动物园zoo信息,其中包括各类动物以及雇员信息,符合restful架构的url可以下设计
5、http动词
对于资源的具体操做类型,由http动词表示,经常使用的http动词以下
两个不经常使用http动词
例子以下
6、信息过滤(filter)
若是资源数量过多,服务器很差一次性所有返回给用户,api应该提供参数,过滤返回结果,好比指定筛选条件,排序,分页,限制返回数量等
参数设计容许冗余,即容许api路径与url参数偶尔重复,好比 get /zoos/id/animals与 get /animals?zooId=id含义相同
7、状态码(status code)
服务器向用户返回的状态码和提示信息,常见的列表如下
8、错误处理(error handling)
若是状态码是4xx,应该向用户返回错误信息,通常来讲,返回的信息中将error做为键名,出错信息做为键值便可
9、返回结果
针对不一样操做,服务器向用户返回的结果应该符合如下规范
10、hypermedia api
restful api最好作到hypermedia,即返回结果中信息丰富一点,提供连接,连向其余api方法,使得用户不用去查询文档,也知道下一步应该作什么。好比当用户向api.test.com的根目录发出请求时,获得的文档包含如下结果
{
"link":{ "rel": "collection http://api.test.com/zoos",
"href": "http://api/test.com",
"title": "list of zoos",
"type": "application/vnd.yourformat+json"
} }
上面代码表示,文档中有一个link属性,用户读取这个属性就知道下一步该调用什么api,rel表明这个api与当前网址的关系(collection关系,并给出该collection网址),href表示api路径,title表示api的标题,type表示返回类型。
hypermedia api的设计也被称为HATEOAS,github的api就是这种设计,请求github的api会获得一个全部可用api网址列表
{ "current_user_url": "https://api.github.com/user", "current_user_authorizations_html_url": "https://github.com/settings/connections/applications{/client_id}", "authorizations_url": "https://api.github.com/authorizations", "code_search_url": "https://api.github.com/search/code?q={query}{&page,per_page,sort,order}", "commit_search_url": "https://api.github.com/search/commits?q={query}{&page,per_page,sort,order}", "emails_url": "https://api.github.com/user/emails", "emojis_url": "https://api.github.com/emojis", "events_url": "https://api.github.com/events", "feeds_url": "https://api.github.com/feeds", "followers_url": "https://api.github.com/user/followers", "following_url": "https://api.github.com/user/following{/target}", "gists_url": "https://api.github.com/gists{/gist_id}", "hub_url": "https://api.github.com/hub", "issue_search_url": "https://api.github.com/search/issues?q={query}{&page,per_page,sort,order}", "issues_url": "https://api.github.com/issues", "keys_url": "https://api.github.com/user/keys", "notifications_url": "https://api.github.com/notifications", "organization_repositories_url": "https://api.github.com/orgs/{org}/repos{?type,page,per_page,sort}", "organization_url": "https://api.github.com/orgs/{org}", "public_gists_url": "https://api.github.com/gists/public", "rate_limit_url": "https://api.github.com/rate_limit", "repository_url": "https://api.github.com/repos/{owner}/{repo}", "repository_search_url": "https://api.github.com/search/repositories?q={query}{&page,per_page,sort,order}", "current_user_repositories_url": "https://api.github.com/user/repos{?type,page,per_page,sort}", "starred_url": "https://api.github.com/user/starred{/owner}{/repo}", "starred_gists_url": "https://api.github.com/gists/starred", "team_url": "https://api.github.com/teams", "user_url": "https://api.github.com/users/{user}", "user_organizations_url": "https://api.github.com/user/orgs", "user_repositories_url": "https://api.github.com/users/{user}/repos{?type,page,per_page,sort}", "user_search_url": "https://api.github.com/search/users?q={query}{&page,per_page,sort,order}" }
从上面能够看到,若是想获取当前用户的信息,应该去访问api.github.com/user,会获得以下返回结果
{ "message": "Requires authentication", "documentation_url": "https://developer.github.com/v3/users/#get-the-authenticated-user" }
返回结果给出了服务器的提示信息,以及相应文档地址
11、其余
api的身份认证可使用Oauth框架
服务器返回的数据格式,尽可能使用json,xml