RESTful APIs存在的问题
基于上次我们对良好API的设计的讨论,我们发现RESTful APIs存在一些问题:
- 以描述资源为主,而API的设计并非只是描述资源的
- 接口是无状态的,而实际的业务都是有状态的。HTTP协议最终通过引入cookies或者session来维持状态,也引入了更多的安全问题。,所以无状态,会增加接口的不安全性。
- 只支持HTTP协议,无法支持Websocket协议或者其它的协议。
- 将协议与应用混合起来, 同时协议动作数量又有限。可以感受明显的耦合与冲突,与良好的API设计是相悖的。
- 过于学术化,不够亲民
- 无法简单的描述清楚
- 同时将所有的接口当成资源不符合实际的互联网业务实际。
实用的,良好的,明确的,面向业务的,新的API规范的需求
所以基于这个问题,我们需要设计一个更加实用的API。
- 将RESTful APIs独立出来成为专门的文件资源的表达
- 将所有业务资源API独立出来,通过一个专门的API规范来定义,我们将这个规范定义成蛋蛋API(egg api)
蛋蛋API
基于上面的讨论,我们认为将文件资源与业务资源分离会是一个更好的选择。
文件资源可以直接基于文件服务器或者基于RESTful APIs的接口,而业务资源通过蛋蛋API来描述。
所以我们要明确蛋蛋API要解决的问题。
面向业务资源
由于蛋蛋API解决的是业务资源的操作与获取,所以需要像RESTful APIs具备很强的自描述性的,从而也不需要基于MIME的文件类型描述。所以我们的返回文件格式只有一种:JSON。
通过JSON可以很好的表达业务资源的数据与业务的操作。
也就是我们不再是Represtative了,而是DATA ONLY。
也就是不再关注如何表达,表示,只关注数据与业务的传递。
错误处理
在RESTful API里错误是基于HTTP Code的方式来表达的。
但是HTTP Code的方式有两个缺点:
- code数量有限
- 错误面向的是协议,与业务的关系性较弱
所以蛋蛋API规定了基于的错误与返回数据格式
API风格与规范
在蛋蛋API中吸收RESTful APIs资源定位的理念,初步建立以下一些基本规范:
- 将业务资源通过URI进行定位
- 通过类HTTP方法实行对资源的操作
- GET方法用于获取业务资源数据,不影响数据变化
- POST方法用于操作数据,可能会导致数据生成,变更,消失。
- API可不限于HTTP协议,也可以适合于可能的HTTP的变种协议
- 明确所有的操作以名词开始。在URI中,不包含可发生资源变更的动词
- 所有变更通过POST提交,并将变更的动词放在action参数下面。
URI的query参数规范
在蛋蛋API里完全将Query当成是查询,但是除去了ID查询。
因为通过URI就可以定位ID查询的结果。
在URI中第一个?号后的参数称为query参数,一般的形式是name=value&name1=value1这样的。
在这里,我们基于HTTP的query,实现对数据的查询。
分页
参数名page表示页码,limit表示每页数据量。
所以获取第5页,每页50个数据的query是这样的:
1 | uri?page=5&limit=50 |
默认值: page=1, limit=20。
会话
如果蛋蛋API的会话是基于token的。token将会被放在query里。
代码示例:
1 | uri?token=xxx |
状态查询
每个业务资源都是可以有状态的,所以我们提供了state来表示状态。
建议所有的状态都使用state来表达。同时状态值使用大写字符串来表达。
代码示例:
1 | uri?state=GOOD |
时间段匹配
在query里面提供了时间查询字串:from, to。
可以单独使用,也可以混合使用。查询格式是 YYYY-MM-DD HH:MM:SS。
可以不断减少精确度,直到只有年。
所以可以是
YYYY-MM-DD HH:MM, YYYY-MM-DD HH, YYYY-MM-DD, YYYY-MM, YYYY
这几种格式。
月日不足10时需要使用0补足。
小时采用24小时制。
代码示例:1
uri?from=1998-09-01&to=2000-01-20 20:10
URI的POST参数规范
由于蛋蛋API采用POST来改变数据,所以我们对POST数据作出如下规范
- 提交的数据要与HTTP的表单提交一致
- 以action字段取代RESTful APIs里面的HTTP方法
- 所以业务变更必须通过类HTTP的表单提交。
- 不能将业务逻辑写在文件里,通过文件提交。比如将业务逻辑写到JSON文件里提交到服务器。
- 所有的变更参数必须通过POST提交。
一个POST示例:
1 |
|
总结
至此我们已经将蛋蛋API与RESTful APIs的一些特点与优缺点描述完整。
我们在文件资源表示时,可以采用RESTful,而在业务表示时,使用蛋蛋API的规范会让你更加的得心应手。所以对于不同的情况采用不同的策略也许是一个更加可行的办法,不拘泥于RESTful APIs还是蛋蛋APIs。也许,你可以发展出来一套更加有效的API。
蛋蛋API的出发点是实现一套更加实用的,不受HTTP约束,更加面向业务的API规范,所以方向与RESTful APIs是不同的。蛋蛋API面向的更多的是业务资源,而REST将所有的内容都当成是资源表达,并不是我们所同意的看法,所以我们有意将蛋蛋API定位于面向业务资源而不是文件资源,从而可以让我们的API变的更加简单,从而不需要Representive,也不需要MIME。
我们遵从常识大于配置的观念,希望通过固化一些共同的属性,达到最大的一致化API。
目前蛋蛋API仍处于早期阶段,仍有很多可以改进与可以规范的地方。
所以非常欢迎对于优化API,改进规范,促成更好的API协作感兴趣的同仁一起参与改进。
egg api规范地址: