RESTful API的编写

你怎么理解 RESTful

2000 年,Roy Thomas Fielding 博士在他那篇著名的博士论文《Architectural Styles and the Design of Network-based Software Architectures》中提出了几种软件应用的架构风格,REST 作为其中的一种架构风格在这篇论文的第5章中进行了概括性的介绍。

REST 是“REpresentational State Transfer”的缩写,可以翻译成“表现状态转换”,但是在绝大多数场合中我们只说 REST 或者 RESTful。Fielding 在论文中将 REST 定位为“分布式超媒体应用(Distributed Hypermedia System)”的架构风格,它在文中提到一个名为“HATEOAS(Hypermedia as the engine of application state)”的概念。

我们利用一个面向最终用户的 Web 应用来对这个概念进行简单阐述:这里所谓的应用状态(Application State)表示 Web 应用的客户端的状态,简单起见可以理解为会话状态。资源在浏览器中以超媒体的形式呈现,通过点击超媒体中的链接可以获取其它相关的资源或者对当前资源进行相应的处理,获取的资源或者针对资源处理的响应同样以超媒体的形式再次呈现在浏览器上。由此可见,超媒体成为了驱动客户端会话状态的转换的引擎。

借助于超媒体这种特殊的资源呈现方式,应用状态的转换体现为浏览器中呈现资源的转换。如果将超媒体进一步抽象成一般意义上的资源呈现(Representation )方式,那么应用状态变成了可被呈现的状态(REpresentational State)。应用状态之间的转换就成了可被呈现的状态装换(REpresentational State Transfer),这就是 REST。

总结:REST 是一种很笼统的概念,它代表一种架构风格。

说说如何设计一个良好的 API

版本号
在 RESTful API 中,API 接口应该尽量兼容之前的版本。但是,在实际业务开发场景中,可能随着业务需求的不断迭代,现有的 API 接口无法支持旧版本的适配,此时如果强制升级服务端的 API 接口将导致客户端旧有功能出现故障。实际上,Web 端是部署在服务器,因此它可以很容易为了适配服务端的新的 API 接口进行版本升级,然而像 Android 端、IOS 端、PC 端等其他客户端是运行在用户的机器上,因此当前产品很难做到适配新的服务端的 API 接口,从而出现功能故障,这种情况下,用户必须升级产品到最新的版本才能正常使用。

为了解决这个版本不兼容问题,在设计 RESTful API 的一种实用的做法是使用版本号。一般情况下,我们会在 url 中保留版本号,并同时兼容多个版本。

【GET】  /v1/users/{
   user_id}  // 版本 v1 的查询用户列表的 API 接口
【GET】  /v2/users/{
   user_id}  // 版本 v2 的查询用户列表的 API 接口

现在,我们可以不改变版本 v1 的查询用户列表的 API 接口的情况下,新增版本 v2 的查询用户列表的 API 接口以满足新的业务需求,此时,客户端的产品的新功能将请求新的服务端的 API 接口地址。虽然服务端会同时兼容多个版本,但是同时维护太多版本对于服务端而言是个不小的负担,因为服务端要维护多套代码。这种情况下,常见的做法不是维护所有的兼容版本,而是只维护最新的几个兼容版本,例如维护最新的三个兼容版本。在一段时间后,当绝大多数用户升级到较新的版本后,废弃一些使用量较少的服务端的老版本API 接口版本,并要求使用产品的非常旧的版本的用户强制升级。

注意的是,“不改变版本 v1 的查询用户列表的 API 接口”主要指的是对于客户端的调用者而言它看起来是没有改变。而实际上,如果业务变化太大,服务端的开发人员需要对旧版本的 API 接口使用适配器模式将请求适配到新的API 接口上。

资源路径

RESTful API 的设计以资源为核心,每一个 URI 代表一种资源。因此,URI 不能包含动词,只能是名词。注意的是,形容词也是可以使用的,但是尽量少用。一般来说,不论资源是单个还是多个,API 的名词要以复数进行命名。此外,命名名词的时候,要使用小写、数字及下划线来区分多个单词。这样的设计是为了与 json 对象及属性的命名方案保持一致。例如,一个查询系统标签的接口可以进行如下设计。
/版本号/资源/{资源id}

【GET】  /v1/tags/{
   tag_id} 

同时,资源的路径应该从根到子依次如下

/{
   resources}/{
   resource_id}/{
   sub_resources}/{
   sub_resource_id}/{
   sub_resource_property}

我们来看一个“添加用户的角色”的设计,其中“用户”是主资源,“角色”是子资源。

【POST】  /v1/users/{
   user_id}/roles/{
   role_id} // 添加用户的角色

有的时候,当一个资源变化难以使用标准的 RESTful API 来命名,可以考虑使用一些特殊的 actions 命名。

/{
   resources}/{
   resource_id}/actions/{
   action}

举个例子,“密码修改”这个接口的命名很难完全使用名词来构建路径,此时可以引入 action 命名。

【PUT】  /v1/users/{
   user_id}/password/actions/modify // 密码修改

请求方式

可以通过 GET、 POST、 PUT、 PATCH、 DELETE 等方式对服务端的资源进行操作。其中:

GET:用于查询资源
POST:用于创建资源
PUT:用于更新服务端的资源的全部信息
PATCH:用于更新服务端的资源的部分信息
DELETE:用于删除服务端的资源。

这里,使用“用户”的案例进行回顾通过 GET、 POST、 PUT、 PATCH、 DELETE 等方式对服务端的资源进行操作。

【GET】 /users # 查询用户信息列表
【GET】 /users/1001 # 查看某个用户信息
【POST】 /users # 新建用户信息
【PUT】 /users/1001 # 更新用户信息(全部字段)
【PATCH】 /user

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值