浅谈RESTful在API设计的应用

最近开发若干工程,有一些问题困惑不解,如何成为一个更好的Coder,如何让接入方在使用过程中的学习成本更小?如何让设计的系统更加符合行业规范?如何体现出一个工程的高质量?

写下这篇文章用于鞭策自己在API设计方向上的思考,会不断更新。该文章仅仅设计HTTP(S)下的API设计,对于内部应用,还是推荐使用RPC进行microservice之间的沟通,虽然目前我们还没有。

先说一下我的几个观点:

    API的设计就是后端程序员的UI,你必须仔细考虑它的用户体验

    我们不应该去追求正宗的RESTful风格,而是愿意使用其思想来处理修饰一些URI

    完全正宗的RESTful固然存在并且被使用了,特别适用于特大项目的开放平台API,对于内部的应用,要不要花大量地时间去遵守各种细节,应该由各个团队自己去权衡

RESTful是什么?

    REST=representationnal state transfer。表述型状态转移。它不是一种标准,而是一种接口设计风格。

    RESTful API指的是按照REST风格来设计的API,它主要有几个特点:

        1.网络上所有的事物都抽象为资源,资源有唯一的标识符

        2.同一个资源有不同的表现形式(JSON/XML/...)

        3.所有的操作都是无状态的(API服务器可水平扩展)

    所以,REST是一种面向资源的架构设计风格,面向资源是最重要的特点。关注“资源”究其本质是关注“数据模型”,能够帮助不同组件更好地解耦,消除依赖关系,以及增大系统扩展性。

    相反地,SOAP的特点是关注行为和处理,与REST有着很大的不同。


标准的使用姿势

如何去测试你的API是否是一个真正的RESTful API?

黄金标准:API=协议+域名+版本+路径+HTTP动词+过滤信息+状态码+错误处理+返回结果

举个例子:

栗子:GET https://api.douban.com/v2/note/user_created/:id?withAll=true

-------动词--协议----------------域名-----------版本------路径----------------------过滤信息----------------


打假过程&&最佳实践

    1.请求方法支持GET/POST/UPDATE/DELETE

    2.请求响应严格遵守HTTP状态码:

    3.返回结果使用JSON

    4.API中有版本的概念

    5.使用token做身份认证

    6.urI中不出现大写字母

    7.urI中使用_连接不同的单词

8.有一份漂亮的文档(尤其重要)

    9.非内网应用使用HTTPS

适用于什么场景?

    RESTful特别适用于开放平台的API开发。对于未知的调用者,你要尽可能地遵守业界的规范,返回尽可能多的信息。

    相反地,对于公司内部的微服务应用,比如电商平台的前后端开发,如果单纯为了REST而ful并不可取。

    很可能,某个渠道的前端的兄弟们已经习惯了把200当做唯一正常的状态码来访问。如果渠道的兄弟们人数众多,为了和谐,还是建议多多沟通然后在新系统上使用RESTful风格设计。

    对于已发布的非REST风格,不建议修改为REST。因为一旦发布,对外的API将很难改变。


存在即合理&&为什么会有RESTful?

    没有RESTful之前,我们是这样调用API的-------有了RESTful之后,我们是这样调用API的

    /api/v1/user/query?uid=1  GET   ------- /api/v1/user/1 GET

    /api/v1/user/delete?uid=1 GET   ------- /api/v1/user/1 DELETE

    /api/v1/user/update?uid=1 POST  ------- /api/v1/user/1 PUT

    /api/v1/user/save              POST  ------- /api/v1/user   POST    

    前者我们在请求URI中定位资源与动作。后者在URI中定位资源、在HTTP METHOD中定位动作。

    网络上大部分的REST相关的博客涉及的内容都是URI的设计或REST的使用规范,但我觉得REST的核心在于,当你设计一个系统的时候,资源是第一位的考虑,你要从资源的角度来进行系统的拆分、设计;而不是像以前一样以操作为角度来进行设计。达成这样的目的:1.容易写出规范化URI,2.规范化使用了HTTP协议,不再只有200和500。

    我们平时是这样设计系统的:有下单功能->下单需要一个URL→往这个URL发送的数据要定义好→开始写前端和后端。我们先确认一个操作,然后围绕这个操作去做业务实现。这样虽然可以设计出好的系统,但是可能会有这样的问题:1.操作之间的关联导致业务的复杂,比如“下单”操作要依赖于“查票”操作之前。2.系统的URI设计缺乏一致性。3.很少规范化使用HTTP状态码。

    深挖下来,我们是把HTTP当做一个传输的通道,还是一个传输的协议?如果只是传输的通道,那么HTTP的状态码应该只有200和500,200代表这条路可以走,500代表走不了。

    如果当做传输的协议,那HTTP本身的状态码其实就规范了很多操作。

大神语录:

REST的目的是“建立十年内不会过时的软件系统架构",所以它具备三个特点:

1. 状态无关 —— 确保系统的横向拓展能力

2. 超文本驱动,Fielding的原话是”hypertext-driven" —— 确保系统的演化能力

3. 对 resource 相关的模型建立统一的原语,例如:uri、http的method定义等 —— 确保系统能够接纳多样而又标准的客户端

从另外一个角度看,第一条保证服务端演化,第三条保证客户端演化,第二条保证应用本身的演化,这实在是一个极具抽象能力的方案。

文章最后的但是:

    1.复杂的关系,操作,资源集合,硬性套用REST原则设计非常困难

       有的动作无法抽象成资源,例如登录。但是我们可以把登录转换成【申请/发放令牌】这几个动作。

    2.状态码完全不够用:比如,登录错误:

       是因为频率限制、账号密码错误、用户不存在...等等原因,最终我们还是要有自己的BizErrorCode。

3.对于不能抽象成资源的:https://api.douban.com/v2/book/search?q=python&fields=id,title

4.多人纠结get(查询)/post(增加)/delete(删除)/put(修改),连Roy Thomas Fielding都这么说,我认为这完全是个误区,因为把软件的业务场景过于简单化了。

       难道我们的系统就只实现这四类操作么,那么我问你,发短信、支付、用户登录认证,这算是哪一个?

你可能感兴趣的:(浅谈RESTful在API设计的应用)