RESTful API 设计指南

作者: 阮一峰

日期: 2014年5月22日

网络应用程序,分为前端和后端两个部分。当前的发展趋势,就是前端设备层出不穷(手机、平板、桌面电脑、其他专用设备......)。

因此,必须有一种统一的机制,方便不同的前端设备与后端进行通信。这导致API构架的流行,甚至出现"API First"的设计思想。RESTful API是目前比较成熟的一套互联网应用程序的API设计理论。我以前写过一篇《理解RESTful架构》,探讨如何理解这个概念。

今天,我将介绍RESTful API的设计细节,探讨如何设计一套合理、好用的API。我的主要参考了两篇文章(12)。

RESTful API

一、协议

API与用户的通信协议,总是使用HTTPs协议

二、域名

应该尽量将API部署在专用域名之下。


https://api.example.com

如果确定API很简单,不会有进一步扩展,可以考虑放在主域名下。


https://example.org/api/

三、版本(Versioning)

应该将API的版本号放入URL。


https://api.example.com/v1/

另一种做法是,将版本号放在HTTP头信息中,但不如放入URL方便和直观。Github采用这种做法。

四、路径(Endpoint)

路径又称"终点"(endpoint),表示API的具体网址。

在RESTful架构中,每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词,而且所用的名词往往与数据库的表格名对应。一般来说,数据库中的表都是同种记录的"集合"(collection),所以API中的名词也应该使用复数。

举例来说,有一个API提供动物园(zoo)的信息,还包括各种动物和雇员的信息,则它的路径应该设计成下面这样。

  • https://api.example.com/v1/zoos
  • https://api.example.com/v1/animals
  • https://api.example.com/v1/employees

五、HTTP动词

对于资源的具体操作类型,由HTTP动词表示。

常用的HTTP动词有下面五个(括号里是对应的SQL命令)。

  • GET(SELECT):从服务器取出资源(一项或多项)。
  • POST(CREATE):在服务器新建一个资源。
  • PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。
  • PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
  • DELETE(DELETE):从服务器删除资源。

还有两个不常用的HTTP动词。

  • HEAD:获取资源的元数据。
  • OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的。

下面是一些例子。

  • GET /zoos:列出所有动物园
  • POST /zoos:新建一个动物园
  • GET /zoos/ID:获取某个指定动物园的信息
  • PUT /zoos/ID:更新某个指定动物园的信息(提供该动物园的全部信息)
  • PATCH /zoos/ID:更新某个指定动物园的信息(提供该动物园的部分信息)
  • DELETE /zoos/ID:删除某个动物园
  • GET /zoos/ID/animals:列出某个指定动物园的所有动物
  • DELETE /zoos/ID/animals/ID:删除某个指定动物园的指定动物

六、过滤信息(Filtering)

如果记录数量很多,服务器不可能都将它们返回给用户。API应该提供参数,过滤返回结果。

下面是一些常见的参数。

  • ?limit=10:指定返回记录的数量
  • ?offset=10:指定返回记录的开始位置。
  • ?page=2&per_page=100:指定第几页,以及每页的记录数。
  • ?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序。
  • ?animal_type_id=1:指定筛选条件

参数的设计允许存在冗余,即允许API路径和URL参数偶尔有重复。比如,GET /zoo/ID/animals 与 GET /animals?zoo_id=ID 的含义是相同的。

七、状态码(Status Codes)

服务器向用户返回的状态码和提示信息,常见的有以下一些(方括号中是该状态码对应的HTTP动词)。

  • 200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。
  • 201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
  • 202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务)
  • 204 NO CONTENT - [DELETE]:用户删除数据成功。
  • 400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。
  • 401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。
  • 403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。
  • 404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。
  • 406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。
  • 410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。
  • 422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。
  • 500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。

状态码的完全列表参见这里

八、错误处理(Error handling)

如果状态码是4xx,就应该向用户返回出错信息。一般来说,返回的信息中将error作为键名,出错信息作为键值即可。


{
    error: "Invalid API key"
}

九、返回结果

针对不同操作,服务器向用户返回的结果应该符合以下规范。

  • GET /collection:返回资源对象的列表(数组)
  • GET /collection/resource:返回单个资源对象
  • POST /collection:返回新生成的资源对象
  • PUT /collection/resource:返回完整的资源对象
  • PATCH /collection/resource:返回完整的资源对象
  • DELETE /collection/resource:返回一个空文档

十、Hypermedia API

RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。

比如,当用户向api.example.com的根目录发出请求,会得到这样一个文档。


{"link": {
  "rel":   "collection https://www.example.com/zoos",
  "href":  "https://api.example.com/zoos",
  "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就是这种设计,访问api.github.com会得到一个所有可用API的网址列表。


{
  "current_user_url": "https://api.github.com/user",
  "authorizations_url": "https://api.github.com/authorizations",
  // ...
}

从上面可以看到,如果想获取当前用户的信息,应该去访问api.github.com/user,然后就得到了下面结果。


{
  "message": "Requires authentication",
  "documentation_url": "https://developer.github.com/v3"
}

上面代码表示,服务器给出了提示信息,以及文档的网址。

十一、其他

(1)API的身份认证应该使用OAuth 2.0框架。

(2)服务器返回的数据格式,应该尽量使用JSON,避免使用XML。

(完)

留言(186条)

最后一条: "服务器返回的数据格式,应该使用JSON,不应使用XML" 存疑,返回某种自描述类的文本类数据即可,貌似没有规定不应使用XML;这与SOAP的rpc风格没有关联,两码事。

如果批量获取指定ID的一堆Zoo,按理应该用GET,但是由于ID列表可能会很长,这样会导致url过长;如果放在HTTP Content里面,但通常只有POST这些才支持,这样又不符合HTTP动词语义。请问如何破解?

API还必须易于测试,能让用户在页面测试API,看到发送和接收的结果。

@fallingwine:

谢谢指出,改了一下。某些场合,确实不得不使用XML。

引用allenwest的发言:

如果批量获取指定ID的一堆Zoo,按理应该用GET,但是由于ID列表可能会很长,这样会导致url过长;如果放在HTTP Content里面,但通常只有POST这些才支持,这样又不符合HTTP动词语义。请问如何破解?

url过长有什么问题?
不会是担心浏览器地址栏里的url长度吧?

這個整理得很好,讚呀。


我想問
如果 發生錯誤時,
只是拋出Status Code 真的好嗎?
如果想回應 錯誤的原因, 例如: 此日期不正確 ,之類

不好意思,忘記了可以更改Response Body.
{"status":"XXX","message":"XXX"}

有关搜索的 API 设计没有提到,是 search?q=?吗?

“理解RESTful架构”这篇文章提到“另一个设计误区,就是在URI中加入版本号”,不是跟上面提到的第三点矛盾了吗?

?sortby=name&order=asc
上面这种方式比较直观,如果用urlrewriter方式也不错,/sortby/name/order/asc,这样似乎又不符合一个url一个资源的规范

POST 一个对象时,对象的内容是怎么放到POST参数里面呢?

是把对象转成一个json,放在一个参数里面。
还是把对象的每个字段当初一个参数?

引用Yhzhtk的发言:

POST 一个对象时,对象的内容是怎么放到POST参数里面呢?

是把对象转成一个json,放在一个参数里面。
还是把对象的每个字段当初一个参数?

转成json放到request body里面。

目前公司也从WCF 向API 方面转移,定义与LZ雷同...

我一般是给 web app使用,但是浏览器对 PUT 这类支持不好,这个操作放到 URL 里合适吗?怎么处理比较好呢?

引用廖雪峰的发言:

API还必须易于测试,能让用户在页面测试API,看到发送和接收的结果。

开发人员一般都是chrome 或 firefox加插件调试

现在移动开发都是用api去调用数据,web也可以一起共用,节约开发成本。

引用Fengz的发言:

我一般是给 web app使用,但是浏览器对 PUT 这类支持不好,这个操作放到 URL 里合适吗?怎么处理比较好呢?


对PUT这类的操作也一直是和你有着同样的困惑。

其实这只是一个推荐规范, 为了解决一些浏览器的HTTP方法的兼容问题, 还有GET URL超长的问题, 感觉可以变通为, 把HTTP方法名称也放入URI中, 如:

/GET/zoos
/PUT/zoos/ID
/DELETE/zoos/ID

过长的参数可以自动使用POST方法来发送

用POST,《RESTful Web Services Cookbook》上有说过。

对于PUT和POST的用法,这篇文章和《RESTful Web Services Cookbook》上推荐的做法不一致。
Cookbook上的做法是如果用户可以决定新创建资源的URL,那么就用PUT,否则用POST。
以及,如果不仅仅是单纯的创建一个资源,类似复杂的工厂方法(会连带创建相关的其他复杂类属性),也用POST。

引用j.w的发言:


开发人员一般都是chrome 或 firefox加插件调试

推荐Fiddler

https://speakerdeck.com/akuzemchak/simple-api-development-with-laravel
这里有一个讲 rest api 的ppt,时代不错,有兴趣的同学可以看一下

restful 略蛋疼,跨域的更新操作怎么破?

引用andrewyang的发言:

“理解RESTful架构”这篇文章提到“另一个设计误区,就是在URI中加入版本号”,不是跟上面提到的第三点矛盾了吗?

同问。。。

引用fromoon的发言:

同问。。。

“理解RESTful架构”的评论里也有关于“版本”讨论,这也许和个人观点有关,我是觉得是可以的。有人在http://stackoverflow.com/questions/972226/how-to-version-rest-uris讨论哪种加版本号的方式更好。

你好 谢谢您的文章 我在我们系统中也使用这种架构 想问一下您 如果返回的数据量比较大的结构化数据 使用哪种方式速度上有优势

引用allenwest的发言:

如果批量獲取指定ID的一堆Zoo,按理應該用GET,但是由於ID列表可能會很長,這樣會導致url過長;如果放在HTTP Content裡面,但通常只有POST這些才支持,這樣又不符合HTTP動詞語義。請問如何破解?

若你使用的是 PHP,可以透過 http://www.hashids.org/php/ 來解決

引用allenwest的发言:

如果批量获取指定ID的一堆Zoo,按理应该用GET,但是由于ID列表可能会很长,这样会导致url过长;如果放在HTTP Content里面,但通常只有POST这些才支持,这样又不符合HTTP动词语义。请问如何破解?

获取一堆的Zoo,你会经常发一堆的ID去查找吗?
我觉得获取列表往往只是发几个过滤条件,或者通过不同的endpoint,就足够了

版本应该在HTTP头中把.我一直认为Rest思想,其实就是HTTP协议的设计初衷.既然HTTP协议本身设计了版本,就应该走协议本身.而不是在协议上扩展.

你还记得你2007写的绕过gfw吗?

请教你:使用p2p技术能否把gfw打成一个千疮百孔的筛子,让其变成一个没有用的马其诺防线?

背景:
越来越受不了被人禁言和国内媒介的噤若寒蝉,特别是最近的事件,假期结束所有新闻平静沉默的吓人。

想法:
12年刚知道 BitCoin时被它的去中心技术所叹服。于是在想如果媒介或沟通也能去中心化,或者每个人都是一个中心,那么“擒贼先擒王”的办法再也无法控制每个单个个体。

方案:
A:去中心沟通工具
(1):做一个沟通工具,之间只能通过p2p链接。
(2):数据加密、源码开放。以BitCoin的方式认证源码。任何人都可以使用任何语言编写工具,但只能被认证通过的才可以进行沟通。防止间谍工具(代码)。
(3):p2p自我发现(嗅探)--每个终端开启后,可以自动嗅探到最近的其它终端,最终达到全网互联。
另:也可以使用初始其它p2p链接。即:一个p2p最终可以初始保存多个(如:1000+)其它p2p地址(如:至少有一个最近的,一个外省的,一个国内的,一个国外的)。相当于多服务器(多中心)。
B:去中心“服务器”
媒介(如:网易)只要服务器在国内或者公司在国内就不可能不受制约(断域名、断Ip、断人)。如果有一个服务器是存在全网(并不位于某一具体机器),那么如果在此服务器上部署的服务是不是就不受任何人控制。
(1):根据现在流行的大数据原理(所有结点构成整个分布式服务器,每个结点都可以充当中央结点)组建全网结点。
(2):每个具体用户贡献一部分cpu和内存、硬盘充当结点。
C:去中心“搜索引擎”
(1):同上,也是去中心“服务器”实现的基础。

引用allenwest的发言:

如果批量获取指定ID的一堆Zoo,按理应该用GET,但是由于ID列表可能会很长,这样会导致url过长;如果放在HTTP Content里面,但通常只有POST这些才支持,这样又不符合HTTP动词语义。请问如何破解?

url的长度在http协议中中没有限制,只是在浏览器中有限制

引用AriesDevil的发言:

有关搜索的 API 设计没有提到,是 search?q=?吗?

同有点疑惑,如果按博主说的api中不能出现动词,那就不能用search了?

《理解RESTful架构》中有一段:另一个设计误区,就是在URI中加入版本号。而本文第3条又说:应该将API的版本号放入URL。两者相互冲突了。我觉得版本号不让人URL更合适一些。

.Net的WebAPI 还不能http跨域调用. AJAX使用JSONP访问是只有GET请求. 怎么扩展?

推荐RESTful API调试插件工具
Chrome:Postman/Advanced Rest Client
Firefox:RESTClient

感觉还是不要在URL里加入版本号的比较好。个人浅见。

引用WKPlus的发言:

同有点疑惑,如果按博主说的api中不能出现动词,那就不能用search了?

在参考了github的AIP后,对于搜索可以这样,你要搜索什么,如users, animals等,你可以在对应的后面加上一个搜索参数q={query},最后的组合是:
/users?q={query}这样的资源路径。

uri 中还是带有版本号好。

引用j.w的发言:


开发人员一般都是chrome 或 firefox加插件调试

配合curl很顺畅的。

应该将API的版本号放入URL。
正中误区
http://www.ruanyifeng.com/blog/2011/09/restful.html
另一个设计误区,就是在URI中加入版本号:

新的设计趋势?

引用fallingwine的发言:

最后一条: "服务器返回的数据格式,应该使用JSON,不应使用XML" 存疑,返回某种自描述类的文本类数据即可,貌似没有规定不应使用XML;这与SOAP的rpc风格没有关联,两码事。

基于JSON的优点,网络服务设计就是应该使用JSON而非陈旧的XML作为返回的数据格式~
这点没错,是时候抛弃XML了~

请问大师,如果顾客在控制台需要 “ 一次 ” 更改3个产品的数量,在后台数据库要如何处理事务回滚(transaction rollback )? 不知道是不是在对的地方问对的问题。。。

引用Mark的发言:

请问大师,如果顾客在控制台需要 “ 一次 ” 更改3个产品的数量,在后台数据库要如何处理事务回滚(transaction rollback )? 不知道是不是在对的地方问对的问题。。。

同问

openstack作为比较火的开源项目,里面有很多Restful API的设计,我觉得其应该经受得住考验,任何问题都可以参考它!

引用andrewyang的发言:

“理解RESTful架构”这篇文章提到“另一个设计误区,就是在URI中加入版本号”,不是跟上面提到的第三点矛盾了吗?

我也是看了上一个,一直记得不加版本号这个说法。

六、过滤信息(Filtering)
有时我们会有比较复杂的过滤比如 : >= , between , || , (color=red && size=s)
这些要怎样用uri来表示呢?

引用nebula的发言:

url过长有什么问题?
不会是担心浏览器地址栏里的url长度吧?

get请求,url是有长度限制的

现在正在做一个基于RESTful API 架构的接口。但是遇到了一些令自己很困扰的问题:
假如每一个设备(devices)是拥有多张设备图片(images)的,那么按照RESTful,我们的URI 设计如下:

现在的设计:
GET /devices/ID/images:获取某个设备的所有图片
GET /devices/ID/images/ID:获取某个设备的某张图片(我们不提供改方法,有人认为没有意义的)
POST /devices/ID/images:给指定设备添加一张图片
PUT /Images/ID:修改某张图片(有疑问)
DELETE /images/ID : 删除某张图片(有疑问)

我觉得合理的设计是:
PUT /devices/ID/Images/ID:修改某个设备的某张图片
DELETE /devices/ID/images/ID : 删除某个设备的某张图片


看到,对于修改和删除某张图片,我是有疑问的,现在的删除是直接通过图片ID进行删除(不管这张图片属于哪一个设备的)。其实真的符合RESTful标准吗? 他们这样设计的理由是:由于图片本身就有自己的图片ID,为什么直接通过ID来删除呢,还非得指定某个设备的图片,然后再删除。

RESTful 强调资源的唯一性,images/ID其实就是唯一的图片资源,而/devices/ID/images/ID也是设备的唯一图片,那么,我都不知道应该采用哪一个URI的设计。

看到很多人提到关于版本号的问题,其实在“理解RESTful架构”一文两个误区中,提到的是资源不要使用URI来区分版本,但是这篇文章中所说的不同版本是指API 的版本,两个其实是不一样的。

个人认为版本放在headers 里更合适。放在url 里 确实有点膈应~
另外如果能讲讲 api 的设计过程。
实践出真知吗。期待 实战 api 设计

引用nebula的发言:

url过长有什么问题?
不会是担心浏览器地址栏里的url长度吧?

不美观?

注册、登录、登出这种api该怎么设计?
endpoint怎么定义,还有请求方法是用什么方法?

看来对REST API 还不够了解。
心是火热的,但路还很漫长,可惜项目不等人。
各类问题都很现实,趋于完善还需要时间。

引用nebula的发言:

url过长有什么问题?
不会是担心浏览器地址栏里的url长度吧?

浏览器url长度取决于 浏览器/服务器中较小的那一个.
这个问题我也是遇到过.在一些复杂查询(GET)时候,常常需要向后台传入多个查询参数,我自己大多数都是走post...

第三点介绍的:应该将API的版本号放入URL。但是在另一篇文章里http://www.ruanyifeng.com/blog/2011/09/restful.html介绍:另一个设计误区,就是在URI中加入版本号:

如果不用RESTFUL API 设计, 现有的HTTPs API 设计, 利用好HTTP协议, 设计上应该 不差到哪儿吧。

有哪位大侠能举例说明一下RESTFUL API 比现有的设计 有站得住脚的优势?

你上一篇博文有说“另一个设计误区,就是在URI中加入版本号”
博文地址:http://www.ruanyifeng.com/blog/2011/09/restful.html
和你当前这篇博文第三条有矛盾

引用kwk1024的发言:

url的长度在http协议中中没有限制,只是在浏览器中有限制

web服务器是有限制的啊!

引用低调学习的发言:

你上一篇博文有说“另一个设计误区,就是在URI中加入版本号”
博文地址:http://www.ruanyifeng.com/blog/2011/09/restful.html
和你当前这篇博文第三条有矛盾

楼主如果看到留言,希望能够分享一下你的看法,或者是业界流行的趋势?

你好,第一次留言,请问我如何使用 DELETE 请求传过去一个主键集合进行批量删除呢?

引用shadyxu的发言:

转成json放到request body里面。

那么在api接口处该如何接收

@华仔_SuHua:

我认为设备图片(images)是一种资源,设备(devices)只是图片的不同形式的条件而已,所以应该设计为 /images/ID?devices={id}

应该是翻译的吧,怎么好像成原创了。。http://www.tuicool.com/articles/goto?id=IRfYna

RESTful 现在是各显神通啊.
期待一个行业大佬给出最佳实践,指导我等小民.

引用某人路过的发言:

应该是翻译的吧,怎么好像成原创了。。http://www.tuicool.com/articles/goto?id=IRfYna

看上去是致敬(贼笑

GET /zoos:列出所有动物园
POST /zoos:新建一个动物园

那么,请问,新建一个动物园的PAGE页面的URL应该怎样定义,即GET到新建动物园的页面,不可能是在/zoos这个所有动物园页面里面进行新建吧?

引用haofly的发言:

GET /zoos:列出所有动物园
POST /zoos:新建一个动物园

那么,请问,新建一个动物园的PAGE页面的URL应该怎样定义,即GET到新建动物园的页面,不可能是在/zoos这个所有动物园页面里面进行新建吧?

页面URI:GET /zoos/creation
提交URI:POST /zoos

文章说了,动词的名词化表示一种服务,也是一种资源。资源不一定是存储在DB里的,静态资源类如image,大家很容易理解,但是创建页面所对应的html也是资源。资源的含义,对于一个系统来说,不仅限DB。本人拙见。

引用童奇的发言:

注册、登录、登出这种api该怎么设计?
endpoint怎么定义,还有请求方法是用什么方法?

同样是这个问题

引用华仔_SuHua的发言:

现在正在做一个基于RESTful API 架构的接口。但是遇到了一些令自己很困扰的问题:
假如每一个设备(devices)是拥有多张设备图片(images)的,那么按照RESTful,我们的URI 设计如下:

现在的设计:
GET /devices/ID/images:获取某个设备的所有图片
GET /devices/ID/images/ID:获取某个设备的某张图片(我们不提供改方法,有人认为没有意义的)
POST /devices/ID/images:给指定设备添加一张图片
PUT /Images/ID:修改某张图片(有疑问)
DELETE /images/ID : 删除某张图片(有疑问)

我觉得合理的设计是:
PUT /devices/ID/Images/ID:修改某个设备的某张图片
DELETE /devices/ID/images/ID : 删除某个设备的某张图片


看到,对于修改和删除某张图片,我是有疑问的,现在的删除是直接通过图片ID进行删除(不管这张图片属于哪一个设备的)。其实真的符合RESTful标准吗? 他们这样设计的理由是:由于图片本身就有自己的图片ID,为什么直接通过ID来删除呢,还非得指定某个设备的图片,然后再删除。

RESTful 强调资源的唯一性,images/ID其实就是唯一的图片资源,而/devices/ID/images/ID也是设备的唯一图片,那么,我都不知道应该采用哪一个URI的设计。

/devices/ID/images/ID 返回
image id

images/ID 返回具体的 image,此处的 ID 就是上面返回的 ID

也就是:
images/ID1 返回具体的 image 资源
/devices/ID2/images/ID3 返回 images ID1,此处的 ID3 是 device 拥有 image 的序号(第几张图片)。

引用cosmic的发言:

同样是这个问题

+1

引用Clarence的发言:

那么在api接口处该如何接收


将request数据中的字节转化为String,就是json格式的String字符串了。

一直不太明白,为什么要用http method来表示操作的类型,GET/PUT/POST/DELETE本身就不太好理解,表现力又有限。除了CURD之外,有时我们远程服务还得提供计算、校验等其他服务,决定用哪个method的时候,总感觉自己玩自己。

引用BTQ的发言:

一直不太明白,为什么要用http method来表示操作的类型,GET/PUT/POST/DELETE本身就不太好理解,表现力又有限。除了CURD之外,有时我们远程服务还得提供计算、校验等其他服务,决定用哪个method的时候,总感觉自己玩自己。


同问,reset api的原则或许适用于简单的资源类服务。不适于要求复杂的操作的业务场景。尤其,是需要对多个不同类的资源进行操作。还是觉得用SOA自然。

也许对企业应用,我们还是用返回json的soa风格好了

有个单词错了:Unprocesable 应该是Unprocessable

想请教一下关于资源的理解,我以前的理解是一个endpoint就是一个资源,每个资源的具体内容是由一条条数据组成的。因此对作者所说的:
GET(SELECT):从服务器取出资源(一项或多项)。
POST(CREATE):在服务器新建一个资源。
PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。
PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
DELETE(DELETE):从服务器删除资源。
就有质疑,我觉得应该是:
Get应该是从指定资源中取出一条或多条数据;
post对应的SQL命令就应该是Insert,而不是Creat。即向指定资源插入一条数据,而不是创建一个资源。
同样,put、patch、和Delete的操作也针对的是数据而不是资源。
不知道我说的对不对?

引用allen的发言:

@华仔_SuHua:

我认为设备图片(images)是一种资源,设备(devices)只是图片的不同形式的条件而已,所以应该设计为 /images/ID?devices={id}

我觉得有图片Id就够了,不同的服务器让图片Id不重复完全可以做到,或者图片Id=服务器Id-文件Id

@华仔_SuHua:

我也一直对这个感到困扰,希望哪个大神能给深入解答下

参考这篇写了用 Node.js 的实现 RESTful API 的练习。刚开始学 Node.js,不知道这样写是否正确,请大家给点意见,谢谢:

https://nodejust.com/node-js-restful-api-tutorial/

第三节 版本 中提到要在URI中加入版本号,但是另一篇文章(写于2011年的http://www.ruanyifeng.com/blog/2011/09/restful.html)却认为不应加入版本号。这是矛盾了吗?

====
在RESTful架构中,每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词,而且所用的名词往往与数据库的表格名对应。一般来说,数据库中的表都是同种记录的"集合"(collection),所以API中的名词也应该使用复数。

====

疑问

RESTful中的resource 和数据库中的table是一一对应的吗? 如果是一一对应关系那么不就成了资源就是数据库中的数据了吗? 难道数据库存储的时候一定要按照资源的结构来? 而不是数据是数据,资源是资源?
我认为数据库中的数据结构只是为了存储资源的时候能够更方便,更快捷,更灵活而且可扩展等,但是资源是业务数据,他不一定就要和数据库中的某个table对应,可以使一个table中的一条数据,也可以是多个表数据的集合或者数据库表中的数据经过抽象加工后的一种数据。

引用fallingwine的发言:

最后一条: "服务器返回的数据格式,应该使用JSON,不应使用XML" 存疑,返回某种自描述类的文本类数据即可,貌似没有规定不应使用XML;这与SOAP的rpc风格没有关联,两码事。

人家说的是避免没有不给使用!

引用skychf的发言:

人家说的是避免没有不给使用!

只是后来改了罢了

有个问题,资源的权限怎么在restful中体现?比如谁可以delete一个指定的雇员

关于URL中加入版本号很多人说跟之前作者说的不一致,好像楼主也没有说必须放在URL中啊,这篇指南跟之前那篇不冲突,“另一种做法是,将版本号放在HTTP头信息中,但不如放入URL方便和直观。Github采用这种做法。” 只是推荐这样做吧!标准时说放在header里面,但是开发和使用还是放在URL里面更方便。

引用xiaoc的发言:

====
在RESTful架构中,每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词,而且所用的名词往往与数据库的表格名对应。一般来说,数据库中的表都是同种记录的"集合"(collection),所以API中的名词也应该使用复数。

====

疑问

RESTful中的resource 和数据库中的table是一一对应的吗? 如果是一一对应关系那么不就成了资源就是数据库中的数据了吗?难道数据库存储的时候一定要按照资源的结构来?而不是数据是数据,资源是资源?
我认为数据库中的数据结构只是为了存储资源的时候能够更方便,更快捷,更灵活而且可扩展等,但是资源是业务数据,他不一定就要和数据库中的某个table对应,可以使一个table中的一条数据,也可以是多个表数据的集合或者数据库表中的数据经过抽象加工后的一种数据。

我也有同样的感觉和认识

引用nebula的发言:

url过长有什么问题?
不会是担心浏览器地址栏里的url长度吧?

RESTful的API又不是专供浏览器端使用
别的HTTP客户端也都可以用啊,而且地址栏url很长并不会导致什么问题产生
即使你想把参数不加在url后面也是有很多办法的
ajax无论get post你都可以将参数放入http request body中
只不过,post方式http mime使得参数被设置为form data了
而get方式,变成了http payload
服务器端的处理上稍作改变就可以了
post的form data和get 方式url传参一回事
而get payload方式,你需要读取body然后自己解析一下,也不是什么难事

RESTful中,webapp跨域的问题有什么比较优雅的解决办法吗?

将版本号加入到URL中更方便直观,将版本号放在HTTP头信息中更简洁纯粹,个人推荐后者。

看了一些文档,现在REST架构一般是PUT用作新建,POST用作更新。
参照:http://restcookbook.com/HTTP%20Methods/put-vs-post/

引用HstarHu的发言:

看了一些文档,现在REST架构一般是PUT用作新建,POST用作更新。
参照:http://restcookbook.com/HTTP%20Methods/put-vs-post/

你真的看清楚了吗?PUT和POST都可用于创建,区别是PUT要有明确的资源地址

最近正好在用 swagger 进行设计,很方便,很多细节都由 swagger specification 自己处理了。

只是,最近发现自动生成的代码框架,有时候会有些 bug.

最近使用spring mvc,有一个疑惑。别人调我的接口,新建一个资源,需要传一系列参数,一些参数是用来判断我新建资源方式的。这些参数放在url上是否更加合适,按照我的理解,post请求的话,body里面存放的是新建的资源内容,而用来做判断的参数放在url上。这样的理解不知道合不合理,希望大神解惑。

简单明了,为什么网上很多文章讲不清楚?

怎么做用户登录 和注册等功能 = =。

引用ppp的发言:

怎么做用户登录 和注册等功能 = =。

关键词:
OAUTH
token

阮老师 最近在看您关于REST的文章,我有一个疑问。您在《理解RESTful架构》一文中有讲到,不要在URI中加入版本号。
但是在本文中,在版本一节,您讲到应该将API的版本号放入URL。

我看到上面的评论对此貌似也有争议,不知道能否解答相应的疑惑,是否应该将版本号加入URL.

您好,我看你提到 API 的认证应该使用 OAuth2 框架。
OAuth2 框架适用于第三方应用对接到某个平台(比如github)并利用其资源提供额外服务,实际上也有利用 OAuth2 实现快捷登录的案例。
那么,内部多个子系统如果分开实现并各自提供自己的 API,那么该如何利用 OAuth2 实现统一认证呢,有没有一些模式推荐呢?谢谢!

引用j.w的发言:


开发人员一般都是chrome 或 firefox加插件调试

或者类似swagger之类的辅助工具

@andy:

比特币?

RESTFul API的书籍和您的博客中提到使用OAUTH做认证,但是却未披露细节。

OAUTH与自己实现Token之类的好像更加重一些。而且API的验证最好能够充分利用Cache(Memcached/Redis),否则RDBS容易成为系统瓶颈。

现在API设计中,API Key,API Secret,Token,Hash等词汇用得很乱。也希望您能够提供一些最佳实践和参考设计。

为什么用zoos而不是zoo呢?如果resource为单位,为什么不是单数呢?

评论比文章要长,说明作者的博客写得确实好

引用木驴的天空的发言:

评论比文章要长,说明作者的博客写得确实好

肚子里有干货,讲出来简洁易懂,评论才这么长吧

受益颇多,感谢!

post 和 put 定义得太绝对了..

确实是一篇好文章,巅峰了我以前的一些想法

引用童奇的发言:

注册、登录、登出这种api该怎么设计?
endpoint怎么定义,还有请求方法是用什么方法?

登录登出的资源是session
登录 POST www.xx.com/session 创建会话
登出 DELETE www.xx.com/session 销毁会话

网址中不能有动词,只能有名词。那么如果我做一个登录功能,允许两种登录方式,用户名/密码 和 手机/验证码,那么只做一个login接口的话,我是需要在后端内部先判断post过来的data里是否有 用户密码或手机验证码,之后再判断变量合法性?感觉后端更臃肿了。
按照之前的旧思路,只要做两个接口 loginByPassword 和 loginByCaptcha 就好了,没有那么多if,代码也会简洁很多。

弱弱的问下大师,支付宝开放平台的接口为什么没有遵循Restful,支付宝那么设计的目的是为了什么呢?

阮大大,我们服务端对支付那块设计是这样的,比如现在要发红包出去,就需要先调用充值接口,然后充值成功后再调用发送红包接口,他说这是遵循restful接口规范,我觉得这不是坑爹吗,各位怎么看,我觉的应该只需要一个接口(想要发红包的充值),服务端知道充值成功后帮我把红包发出去才对

引用石樱灯笼的发言:

网址中不能有动词,只能有名词。那么如果我做一个登录功能,允许两种登录方式,用户名/密码 和 手机/验证码,那么只做一个login接口的话,我是需要在后端内部先判断post过来的data里是否有 用户密码或手机验证码,之后再判断变量合法性?感觉后端更臃肿了。
按照之前的旧思路,只要做两个接口 loginByPassword 和 loginByCaptcha 就好了,没有那么多if,代码也会简洁很多。

如果遵循restful规范,假设登录成功的结果是建立一个session,那么接口可以分别定义为
POST www.xx.com/session?from=password;
POST www.xx.com/session?from=captcha。
不过感觉restful是指单一资源的状态转换,而实际应用中有很多情况很复杂,完全用restful表示实在是有点捉襟见肘,所以你的方法也可以,只要组织内部统一就可以了。

请问:有些浏览器不支持前端的DELETE PUT等方法,这个有什么规范的解决方案吗?

引用陈老师的发言:

阮大大,我们服务端对支付那块设计是这样的,比如现在要发红包出去,就需要先调用充值接口,然后充值成功后再调用发送红包接口,他说这是遵循restful接口规范,我觉得这不是坑爹吗,各位怎么看,我觉的应该只需要一个接口(想要发红包的充值),服务端知道充值成功后帮我把红包发出去才对

规范是死的,人是活的,在具体开发中,不可能完全依赖规范,你说的这个,根本不需要两次,两次请求会有事物问题。

引用BTQ的发言:

一直不太明白,为什么要用http method来表示操作的类型,GET/PUT/POST/DELETE本身就不太好理解,表现力又有限。除了CURD之外,有时我们远程服务还得提供计算、校验等其他服务,决定用哪个method的时候,总感觉自己玩自己。

是的,复杂的系统这个根本无法很好的设计,权限怎么控制?复杂的业务要操作很多种资源的时候url怎么体现?我觉得动作还是放在url上合适

Delete批量操作时,有什么比较认可的方式实现么。

看你的博客(http://www.ruanyifeng.com/blog/2014/05/restful_api.html)RESTful API 设计指南,请教你一个关于RESTful API 设计的问题。谢谢。
RESTful API 校验的问题,对客户端发过来的request json 进行校验。这个应该也是设计的一个重要的环节。如何对request json 如何进行基础的校验。(基础校验包含json某些字段的基本数据类型,某些数据的长度校验等)。请问你有没有好的解决的方法?如果有,请指点,感谢!

另一篇博客 理解RESTful架构 中说一个设计误区就是把版本号写在url中,这篇博客又写着将版本号放入url中?

如果要 批量删除呢?
DELETE /zoos/IDS:删除多个动物园 那么url 不就变成了 DELETE /zoos/1,23,444,3 ?

版本号到底放不放到uri里面>

引用年糕大侠的发言:

版本号到底放不放到uri里面>

同问

文中说“API的身份认证应该使用OAuth 2.0框架。”
OAuth不是授权的框架吗?单单的一个身份验证为什么要使用OAuth呢?

PATCH /collection/resource:返回完整的资源对象

这个应该是客户端上传什么返回什么

请问 RESTful 在ci中使用redis 返回的json格式就不对了 。缺少后半部分 少个中括号 花括号什么的。 $autoload['libraries'] = array('redis', 'database'); 去掉redis 格式就返回正常, 有遇到这种情况的吗。。。。

很详细的资料,学习了!
很多REST Client是不支持自动化测试RESTful API,也不支持自动生成API文档.
有个小工具WisdomTool REST Client,支持自动化测试RESTful API,输出精美的测试报告,并且自动生成精美的RESTful API文档。轻量级的工具,功能却很精悍哦!
https://github.com/wisdomtool/rest-client

可以理解为,路径加请求方法(get,post,put等),就是restful?

请问当多个团队同时维护同一个资源时,应该采用怎样的办法,对资源自身属性进行增加的时候,所有团队都能知晓,并且使用?

看了您的博客,深感觉悟

看了您的博客,深感觉悟

看了您的博客,如醍醐灌顶,谢谢分享!

RESTFUL架构理解中你说版本放到URI是设计误区,为什么这里又让放到URL中

楼上这个问题我也想问,大势所趋?

引用Mark的发言:

请问大师,如果顾客在控制台需要 “ 一次 ” 更改3个产品的数量,在后台数据库要如何处理事务回滚(transaction rollback )? 不知道是不是在对的地方问对的问题。。。

用同一个session去处理,失败了全部回滚不行?

本文和前一篇文章讲到的设计API 误区:带版本号 是相冲突的。
http://www.ruanyifeng.com/blog/2011/09/restful.html

我并不认为API 带版本号是一定是错误的做法,能详细解释一下为什么不建议带版本号吗

对于第四点 路径(Endpoint),有不同的看法,如果资源和库表对应,那么在库表命名中推荐用单数名称[参考](https://blog.csdn.net/lizeyang/article/details/41556803)
那么api中就应该用单数,而不是复数
表示的是需要某种资源,而不关注这种资源是0个1个或者多个

个人见解,欠妥请指正,谢谢

想问一个问题,根据上面文档我整理一下:

GET /post 获取文章列表 返回文章列表(数组)
GET /post/:id:获取文章详情 返回单个资源对象
POST /post/:id:添加文章 返回新生成的资源对象
PUT /post/:id:更新文章 返回完整的资源对象
PATCH /post/:id:更新文章 返回完整的资源对象
DELETE /post/:id:删除文章 返回一个空文档

GET /post?page=1 这样子获取文章列表也可以进行分页展示

但是我想知道全部文章计数以及一些页数之类的我应该这么返回比较好呢?

请教一下,GET方法的API设计。Restful都是通过主键获取单条记录的,如GET /zoos/ID,如果通过其他有唯一约束的字段获取单条记录的话,API要如何设计比较好呢?

感谢!想问一下Sean问的如果有其他约束字段或者需要根据其他条件查询的时候应该如何做呢?

引用synchronized的发言:

是的,复杂的系统这个根本无法很好的设计,权限怎么控制?复杂的业务要操作很多种资源的时候url怎么体现?我觉得动作还是放在url上合适

我现在也是做ERP的时候很多的业务逻辑操作和数据表没有啥关系,同事说用REST,但是我现在研究结果是,如果说把各种操作当服务资源,那不得搞几万个服务,比如说含价格的列表,含库存的列表,。。这种不同的访问,如果用资源来定义,那都是一个新的服务了。。那真的很蛋疼的。。REST的逻辑也就适用于CURD,有大量的业务操作的时候很鸡肋啊。。还请大神赐教!

深入浅出,通俗易懂,收获良多。
然两点不解,烦请指教。

1、在“六、过滤信息”中提到“参数的设计允许存在冗余,即允许API路径和URL参数偶尔有重复。比如,GET /zoo/{ID}/animals 与 GET /animals?zoo_id={ID} 的含义是相同的。”我并未在这个例子中看到什么重复,请问能方便解释一下吗?

2、在“十、Hypermedia API”中提到“rel表示这个API与当前网址的关系(collection关系,并给出该collection的网址)”,这里例子中的“collection关系”指的是是什么呢?

请问请求头的 content-type 一定是 json 格式吗?
如果是,那如何用 restful 如何上传文件?

200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。

如果有新的内容加入进来,那么结果就会变化了,这个是对的吗?
还是我的幂等理解错了。

@atwind:

“幂等性”指的是 1 次或 N 次的副作用(对系统造成的影响)相同,而不是返回结果相同,因此 GET 请求总是幂等的。

restful api用在应用系统中对单表的GRUD合适, 用在复杂的查询和不涉及表的业务api上有点硬套的感觉, 我觉得只要接口写的易于维护, 我不restful又能如何

关于 第7个章节,401和403的描述不准确

401 Unauthorized 应该是没有通过 “认证”,需要用户通过令牌、用户名密码认证完成,才能访问系统。
403 Forbidden 表示用户没有获得“授权”,系统的部分功能未对用户授权,用户的访问是被禁止的。

引用nebula的发言:

url过长有什么问题?
不会是担心浏览器地址栏里的url长度吧?

这个问题面试被问到过,当HTTP请求的数据过长时,选择get还是post好?

引用陈老师的发言:

阮大大,我们服务端对支付那块设计是这样的,比如现在要发红包出去,就需要先调用充值接口,然后充值成功后再调用发送红包接口,他说这是遵循restful接口规范,我觉得这不是坑爹吗,各位怎么看,我觉的应该只需要一个接口(想要发红包的充值),服务端知道充值成功后帮我把红包发出去才对

我觉得设计成两个接口很有道理吧,充值和发红包是两步操作,集成在一个接口里就无法复用,只能处理单一业务场景

很想问下大大,在api中假如版本号的做法是不是规范的,是否建议这样做?

深入浅出

说句不是很高大上的话,这设计重心完全是在设计uri,后台感觉没什么调整吧,那些服务还是那些服务,只不过按照现在的设计理念"服务"叫"软件",对于j2ee来讲,spring框架考虑了这套设计。我真不知道这套设计核心可玩味的地方在哪儿?

6年了还有人回复,现在RESTful成熟了吗?

刚刚看到上一篇《理解RESTful架构》里面说到设计误区是在URI中加入版本号,为什么这篇文章又赞成这样做了

前端是如何发送的RESTFUL,后端是如何进行识别的,这个讲的优点太浅了

有多少公司真正按RESTful来做?

大神,想要请教两个问题,关于restful风格的api接口

如果在请求资源的时候,比如说我用post方法创建一个订单数据,发现用户不存在,或者用户的账户的金额不存在等等,我把这种情况统称为业务异常,如果出现这类的业务异常,我应该怎么去设置http状态码呢?

restful的api接口,客户端根据http状态码来知道是否出现错误,如果http状态码相同,客户端如何区分两种不同的错误呢?比如上面我这边要怎么区分是用户账户不存在,还是用户账户的金额不足呢?

登录和登出没有改变服务端资源,只是让服务器重设了客户的token cookie,那么按理来说应该用get请求,但是我看到现在网上很多都说应该使用post,请问这种应该怎么选择?

引用啁啾的发言:

登录和登出没有改变服务端资源,只是让服务器重设了客户的token cookie,那么按理来说应该用get请求,但是我看到现在网上很多都说应该使用post,请问这种应该怎么选择?

我想我已经指定答案了,登录用post,登出用delete

我也很疑惑,如果使用Restful风格,定义接口数量是有限的,比如:
GET /articles
GET /articles?published=true
GET /articles?title=标题1
GET /articles?pageNum=1&pageSize=10
使用SpringMVC会被mapping成一个接口,根本就不能这么定义

引用fallingwine的发言:

最后一条: "服务器返回的数据格式,应该使用JSON,不应使用XML" 存疑,返回某种自描述类的文本类数据即可,貌似没有规定不应使用XML;这与SOAP的rpc风格没有关联,两码事。

睁大眼睛看清楚:原文是:“应该尽量使用JSON,避免使用XML”

企业都是按照前后端分离做的吗?

刚刚看到上一篇《理解RESTful架构》里面说到设计误区是在URI中加入版本号,为什么这篇文章又赞成这样做了

引用飞流的发言:

我也很疑惑,如果使用Restful风格,定义接口数量是有限的,比如:
GET /articles
GET /articles?published=true
GET /articles?title=标题1
GET /articles?pageNum=1&pageSize=10
使用SpringMVC会被mapping成一个接口,根本就不能这么定义

我怎么觉得这本来就该是一个接口,使用不同的查询条件而已

九、返回结果,里面的patch写错了,可以修改一下。

4开头的状态码还是挺有用的,prod env可以参考

REST API 设计规范与最佳实践 https://github.com/Highflyer/REST_API_DESIGN_GUIDE

引用flynn的发言:

有多少公司真正按RESTful来做?

很多面试的时候都会要求的

引用fallingwine的发言:

最后一条: "服务器返回的数据格式,应该使用JSON,不应使用XML" 存疑,返回某种自描述类的文本类数据即可,貌似没有规定不应使用XML;这与SOAP的rpc风格没有关联,两码事。

说的难道不是“尽量使用json,避免使用xml”, 没说不让你用吧,呵呵

状态码" 201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。",这句有点疑惑,链接w3c文档里写的是新资源创建才201,但是这里修改数据也返回201,意思是更新后的数据也属于新资源来理解嘛?

个人认为RESTful接口规范太桎梏于http协议,不足于表达api接口的语义

https://www.cnblogs.com/JiKang/p/14179913.html
这里最后一节写了我对api接口设计的理解,请阮大侠指教:)

GET /collection:返回资源对象的列表(数组)
对于获取的数据没有安全性要求可以使用GET,对于有安全性要求的数据例如,身份证信息,银行账户,密码等信息,个人认为还是不建议使用GET方法,即使进行了相应的数据加密也不建议使用,以及响应的数据字节长度有一定量也不建议使用GET方法,RESTful接口设计风格还是应该按照实际需求来使用而不是一味按照RESTful接口设计风格死板硬套来进行设计

200 不止是 GET 方法的返回,也不一定是幂等的。是否幂等和 http status 没关系,得看 request

put和post搞反了吧,put是放置,就看字面意思,它也不用来更新,我理解put是新建替换,post是更新或其他非增删改查的动作

引用allenwest的发言:

如果批量获取指定ID的一堆Zoo,按理应该用GET,但是由于ID列表可能会很长,这样会导致url过长;如果放在HTTP Content里面,但通常只有POST这些才支持,这样又不符合HTTP动词语义。请问如何破解?

ID长就应该考虑修改ID参数,因为长ID对于数据库也是不友好

引用allenwest的发言:

如果批量获取指定ID的一堆Zoo,按理应该用GET,但是由于ID列表可能会很长,这样会导致url过长;如果放在HTTP Content里面,但通常只有POST这些才支持,这样又不符合HTTP动词语义。请问如何破解?

改用POST时就果断用,不要让通用的规范成为教条,我可以举出100个RESTful标准无法应对的场景

只考虑“增删改查”而忽略“增删改查”背后丰富的业务动作,我可以举出100个REST无法使用的业务场景(用例)
一线程序员面对的业务需求,可不搞学术的做出来的教条所能相比的

REST感觉充其量就是一个url定义规范,有说这是什么restful架构,怎么上升到架构层次的,它分明对后端根本就是毫无约束也毫无指导意义呀?
而且项目稍微复杂一点,怎么可能只有对一个对象的增删改查?可能一个请求会涉及到无数个资源对象,这按restful该怎么设计?难道你能在url里面把这n个对象都列出来吗?
感觉这规范就是个没实际用处的东西,就是个url设计参考罢了。

引用allenwest的发言:

如果批量获取指定ID的一堆Zoo,按理应该用GET,但是由于ID列表可能会很长,这样会导致url过长;如果放在HTTP Content里面,但通常只有POST这些才支持,这样又不符合HTTP动词语义。请问如何破解?

这种如果要遵守 RESTful规范的话应该是先用 post创建一个查询,返回查询 id。然后再用 get请求去获取查询。不过个人觉得没必要,直接用 post请求就好,这样做除了破坏了 RESTful规范之外好像也没有其他坏处。

引用allenwest的发言:

如果批量获取指定ID的一堆Zoo,按理应该用GET,但是由于ID列表可能会很长,这样会导致url过长;如果放在HTTP Content里面,但通常只有POST这些才支持,这样又不符合HTTP动词语义。请问如何破解?

我处理过这个业务,分两步。第一步先POST把ID集合提交给服务端,服务端返回一个唯一的UUID之类的标识,再GET请求带上这个UUID,服务端关联上ID集合处理

设计时遇到一个问题,比如需要提供新增一个用户的API是,POST /users,那么如果需要提供批量新增用户的API时, POST /users就跟之前的API重复了,那么批量新增的API应该如何设计

引用weihao的发言:

登录登出的资源是session
登录 POSTwww.xx.com/session创建会话
登出 DELETEwww.xx.com/session 销毁会话

会话是某种不常用的说法
登入 、 登出 本身也可以做状态名词,这样都用POST也说的过去,也方便理解

引用andrewyang的发言:

“理解RESTful架构”这篇文章提到“另一个设计误区,就是在URI中加入版本号”,不是跟上面提到的第三点矛盾了吗?

同问,我也发现了。

请问,查询某个状态,返回某个状态信息,查询数据是否存在,导入、导出,这种接口的资源如何设计,

restful api接口感觉覆盖不了所有场景,我有两个问题:
1、查询某个状态,返回某个状态信息,查询数据是否存在,查询两个表之间的影射关系,导入、导出,这种接口的资源如何设计,有的用名词覆盖不到,为了保证接口只扩展,不修改的原则,怎么用restful设计报答呢?
2、API的版本管理策略中,如果接口放在URL中,有一个接口很稳定,一直是V1接口,比如字典接口,另一个接口不稳定已经V8了,那我对外提供时是要让V1与V8进行对齐,还是保持原装,有没有必须要把两个接口的版本拉齐。如果要拉齐,是用版本继承还是拷贝代码方式呢?
感谢!

看了一下相关的文章,但是在定义路由的时候仍然有不少疑惑,比如我们查询多条数据的时候,需要有“列表”、“分页”、“树状结构”三种形式的结构,此刻应当如何定义接口?使用一个接口来返回这三种不同的结构显然不太合适,十分容易让人产生割裂感。

假设我们使用 GET /users/list 来获取列表,那么 users 本身就是复数形式,表示多个用户,后面追加 /list 感觉多此一举;但是如果不添加,我该如何与分页和树状结构区分出来?

同样,如果我们定义出相关的接口为 “/users/tree”、“/users/pagination”,就会十分别扭。

有时候会纠结一些

比如绑定企业微信,解绑企业微信

/user/bindWework
/user/unbind

是否合理?有的时候真的很难不带动词,一般类似这种药怎么命名呢?

我要发表看法

«-必填

«-必填,不公开

«-我信任你,不会填写广告链接