API应该对程序员友好,并且在浏览器地址栏容易输入。
API应该简单,直观,容易使用的同时优雅。
API应该具有足够的灵活性来支持上层ui。
一旦定义好了要暴露的资源,你可以定义资源上允许的操作,以及这些操作和你的API的对应关系:
GET /tickets # 获取ticket列表
GET /tickets/12 # 查看某个具体的ticket
POST /tickets # 新建一个ticket
PUT /tickets/12 # 更新ticket 12.
DELETE /tickets/12 #删除ticekt 12
可以看出使用REST的好处在于可以充分利用http的强大实现对资源的CURD功能。而这里你只需要一个endpoint:/tickets,再没有其他什么命名规则和url规则了
如何处理关联?关于如何处理资源之间的管理REST原则也有相关的描述:
GET /tickets/12/messages- Retrieves list of messages for ticket #12
GET /tickets/12/messages/5- Retrieves message #5 for ticket #12
POST /tickets/12/messages- Creates a new message in ticket #12
PUT /tickets/12/messages/5- Updates message #5 for ticket #12
PATCH /tickets/12/messages/5- Partially updates message #5 for ticket #12
DELETE /tickets/12/messages/5- Deletes message #5 for ticket #12
其中,如果这种关联和资源独立,那么我们可以在资源的输出表示中保存相应资源的endpoint。然后API的使用者就可以通过点击链接找到相关的资源。如果关联和资源联系紧密。资源的输出表示就应该直接保存相应资源信息。(例如这里如果message资源是独立存在的,那么上面 GET /tickets/12/messages就会返回相应message的链接;相反的如果message不独立存在,他和ticket依附存在,则上面的API调用返回直接返回message信息)
不符合CURD的操作
对这个令人困惑的问题,下面是一些解决方法:
重构你的行为action。当你的行为不需要参数的时候,你可以把active对应到activated这个资源,(更新使用patch).
以子资源对待。例如:github上,对一个gists加星操作:PUT /gists/:id/star 并且取消星操作:DELETE /gists/:id/star.
有时候action实在没有难以和某个资源对应上例如search。那就这么办吧。我认为API的使用者对于/search这种url也不会有太大意见的(毕竟他很容易理解)。只要注意在文档中写清楚就可以了。
永远使用SSL
毫无例外,永远都要使用SSL。你的应用不知道要被谁,以及什么情况访问。有些是安全的,有些不是。使用SSL可以减少鉴权的成本:你只需要一个简单的令牌(token)就可以鉴权了,而不是每次让用户对每次请求签名。
值得注意的是:不要让非SSL的url访问重定向到SSL的url。
文档
最好能提供文档在线管理
结果过滤,排序,搜索:
url最好越简短越好,和结果过滤,排序,搜索相关的功能都应该通过参数实现(并且也很容易实现)。
过滤:为所有提供过滤功能的接口提供统一的参数。例如:你想限制get /tickets 的返回结果:只返回那些open状态的ticket–get /tickektsstate=open这里的state就是过滤参数。
排序:和过滤一样,一个好的排序参数应该能够描述排序规则,而不业务相关。复杂的排序规则应该通过组合实现:
GET /ticketssort=-priority- Retrieves a list of tickets in descending order of priority
GET /ticketssort=-priority,created_at- Retrieves a list of tickets in descending order of priority. Within a specific priority, older tickets are ordered first
这里第二条查询中,排序规则有多个rule以逗号间隔组合而成。
搜索:有些时候简单的排序是不够的。我们可以使用搜索技术(ElasticSearch和Lucene)来实现(依旧可以作为url的参数)。
GET /ticketsq=return&state=open&sort=-priority,created_at- Retrieve the highest priority open tickets mentioning the word ‘return’
对于经常使用的搜索查询,我们可以为他们设立别名,这样会让API更加优雅。例如:
get /ticketsq=recently_closed -> get /tickets/recently_closed.
限制API返回值的域
有时候API使用者不需要所有的结果,在进行横向限制的时候(例如值返回API结果的前十项)还应该可以进行纵向限制。并且这个功能能有效的提高网络带宽使用率和速度。可以使用fields查询参数来限制返回的域例如:
GET /ticketsfields=id,subject,customer_name,updated_at&state=open&sort=-updated_at
更新和创建操作应该返回资源
PUT、POST、PATCH 操作在对资源进行操作的时候常常有一些副作用:例如created_at,updated_at 时间戳。为了防止用户多次的API调用(为了进行此次的更新操作),我们应该会返回更新的资源(updated representation.)例如:在POST操作以后,返回201 created 状态码,并且包含一个指向新资源的url作为返回头
鉴权 Authentication
restful API是无状态的也就是说用户请求的鉴权和cookie以及session无关,每一次请求都应该包含鉴权证明。
通过使用ssl我们可以不用每次都提供用户名和密码:我们可以给用户返回一个随机产生的token。这样可以极大的方便使用浏览器访问API的用户。这种方法适用于用户可以首先通过一次用户名-密码的验证并得到token,并且可以拷贝返回的token到以后的请求中。如果不方便,可以使用OAuth 2来进行token的安全传输。
支持jsonp的API需要额外的鉴权方法,因为jsonp请求无法发送普通的credential。这种情况下可以在查询url中添加参数:access_token。注意使用url参数的问题是:目前大部分的网络服务器都会讲query参数保存到服务器日志中,这可能会成为大的安全风险。
注意上面说到的只是三种传输token的方法,实际传输的token可能是一样的。
缓存
HTTP提供了自带的缓存框架。你需要做的是在返回的时候加入一些返回头信息,在接受输入的时候加入输入验证。基本两种方法:
ETag:当生成请求的时候,在HTTP头里面加入ETag,其中包含请求的校验和和哈希值,这个值和在输入变化的时候也应该变化。如果输入的HTTP请求包含IF-NONE-MATCH头以及一个ETag值,那么API应该返回304 not modified状态码,而不是常规的输出结果。
Last-Modified:和etag一样,只是多了一个时间戳。返回头里的Last-Modified:包含了 RFC 1123 时间戳,它和IF-MODIFIED-SINCE一致。HTTP规范里面有三种date格式,服务器应该都能处理。
出错处理
就像html错误页面能够显示错误信息一样,API 也应该能返回可读的错误信息–它应该和一般的资源格式一致。API应该始终返回相应的状态码,以反映服务器或者请求的状态。API的错误码可以分为两部分,400系列和500系列,400系列表明客户端错误:如错误的请求格式等。500系列表示服务器错误。API应该至少将所有的400系列的错误以json形式返回。如果可能500系列的错误也应该如此。json格式的错误应该包含以下信息:一个有用的错误信息,一个唯一的错误码,以及任何可能的详细错误描述。如下:
{
"code" : 1234,
"message" : "Something bad happened :-(",
"description" : "More details about the error here"
}
对PUT,POST,PATCH的输入的校验也应该返回相应的错误信息,例如:
{
"code" : 1024,
"message" : "Validation Failed",
"errors" : [
{
"code" : 5432,
"field" : "first_name",
"message" : "First name cannot have fancy characters"
},
{
"code" : 5622,
"field" : "password",
"message" : "Password cannot be blank"
}
]
}
HTTP 状态码
200 ok - 成功返回状态,对应,GET,PUT,PATCH,DELETE.
201 created - 成功创建。
304 not modified - HTTP缓存有效。
400 bad request - 请求格式错误。
401 unauthorized - 未授权。
403 forbidden - 鉴权成功,但是该用户没有权限。
404 not found - 请求的资源不存在
405 method not allowed - 该http方法不被允许。
410 gone - 这个url对应的资源现在不可用。
415 unsupported media type - 请求类型错误。
422 unprocessable entity - 校验错误时用。
429 too many request - 请求过多。
原文链接:Vinay Sahni,编译:感谢@bruce-accumulate 的热心翻译
译文链接:http://blog.jobbole.com/41233/
分享到:
相关推荐
RESTful API设计规范.pdf RESTful API设计规范是指在软件架构和设计风格中,遵循一组设计原则和约束条件,以降低开发的复杂性,提高系统的可扩展性。RESTful架构的核心是面向资源,每个网址代表一种资源,因此网址...
### RESTful API设计规范详解 #### 一、RESTful简介 RESTful是一种广泛应用于Web服务的设计风格,全称为Representational State Transfer(表述性状态转移)。它并非一项具体的技术标准,而是一系列设计原则和约束...
以下是对RESTful API设计核心概念的详细解释: 1. **资源**:在RESTful API中,资源是系统中的核心实体,例如“tickets”或“messages”。资源通过唯一的URI(统一资源标识符)进行定位,使得客户端可以通过HTTP...
RESTfulAPI设计:RESTfulAPI设计基础.docx
在当今的软件开发领域,RESTful API设计已成为构建可扩展、易于维护的Web服务的关键。C#作为一种强大的编程语言,结合ASP.NET Core框架,为设计和实现RESTful API提供了强大的支持。本文将探讨C#中RESTful API设计的...
RESTfulAPI设计:RESTfulAPI安全性设计.docx
RESTful API 设计 RESTful API 设计是一种架构风格,而不是严格的标准,它有很大的灵活性。它描述了一个架构样式的网络系统,RESTful 架构将服务器成前端服务器和后端服务器两部分,前端服务器为用户提供无模型的...
本文将深入探讨RESTful API设计的基础知识,包括其核心概念、原则和最佳实践。 REST(Representational State Transfer,表现层状态转移)是一种架构风格,源于Web的原始设计原则,由Roy Fielding在他的博士论文中...
这是一个基于Flask的MVC分层RESTful API设计,使用Python、JavaScript、Vue、HTML和CSS语言...该项目是一个采用MVC分层、RESTful API和JSON API设计模式的Flask框架,适合用于个人学习和实践Python和Vue的开发技术。
RESTful API设计是一种遵循REST(Representational State Transfer)架构风格的API设计方法,由Roy Fielding博士在其2000年的博士论文中提出。REST强调的是通过网络进行交互的资源导向性,它定义了一组原则和约束,...
RESTful API设计的核心是资源的CRUD(创建、读取、更新、删除)操作。GET用于检索资源,POST用于创建新资源,PUT用于替换现有资源,PATCH用于部分更新资源,而DELETE则用于删除资源。使用HTTP方法的好处在于,它们的...
#### 二、RESTful API设计原则 在设计RESTful API时,应遵循以下原则: 1. **无状态性**:每次请求都应该包含理解该请求所需的所有信息,服务器不应存储任何客户端的状态信息。 2. **统一接口**:通过使用标准HTTP...
RESTful API设计风格使得接口清晰、易于理解和使用。 ### 2. PHPBoot特点 - **简化的路由配置**:PHPBoot提供了简单的路由定义方式,支持路径参数和HTTP方法的映射,减少了大量重复代码。 - **自动数据验证**:...
RESTful API设计:错误处理与API设计.docx
### RESTful-API设计原则与规范 #### 一、背景与基础概念 RESTful架构作为一种流行的互联网软件架构,因其结构清晰、符合标准、易于理解和扩展等特点而受到广泛青睐。REST(Representational State Transfer)的...
RESTful api设计
RESTful API设计:API版本控制策略.docx
RESTful API设计:API测试方法与工具.docx