说到接口请求规范,我们最耳熟能详的就是restful规范。但是其对是否适用所有公司的不同项目却饱受争议。也是我们讨论最多的问题,所有就会出现公司规定所有接口都用 POST请求这样的情况。
首先我们看一下POST和GET的区别:
-
post更安全(不会作为url的一部分,不会被缓存、保存在服务器日志、以及浏览器浏览记录中)
-
post发送的数据更大(get有url长度限制)
-
post能发送更多的数据类型(get只能发送ASCII字符)
-
post比get慢
-
post用于修改和写入数据,get一般用于搜索排序和筛选之类的操作
-
get请求的是静态资源,则会缓存,如果是数据,则不会缓存
我们发现,POST在发送数据量大的请求时优势很明显,GET则更适合获取静态资源、简单的查询等接口。
然后我们来讨论一下restful的好处:
-
表达不同的业务动作语义:GET/POST/PATCH/PUT/DELETE……,
-
表达“资源”的概念利用
-
url path,querystring,header,status code等来表达很多接口功能
-
以上两条可以达成一种“统一”的接口表达形式,以至于可以围绕这个形式实现接口维护的工具,比如swagger。
-
Get资源可以利用缓存
restful的缺点
- 强行统一,让本来天然不是资源的业务概念也一定要强行“资源“一下,引发了更多的理解不一致和沟通困难。
- 乱折腾path,querysting等东西,让横切面治理抓取关键信息更难了。
- 即使使用swagger,还是需要写说明和文档来说明其业务语义。
- Cache虽好,但最怕的是管控不到位让用户拿到了过期数据。
- 使用形式各异的method和url path,querystring上做各种奇怪的拼接,会给前端带来巨大的困扰
-
非GET和POST之外的method有可能会被不恰当的网关转发规则给干掉。为此Restful还是搞出了method override这样的招数……
总结:
有人举了Google S3运用Restful接口的例子来说明其正确性。但S3是干什么的大家都懂,S3天然就是用来存取“资源“的。一个工具用在了恰当场景,当然是”正确“的。S3用的好的东西,只能说明类似的阿里云OSS,腾讯云COS也可以这么干。但无法证明电商业务、社交业务、I医疗业务、政企办公协同……这些业务也适合这么干。
restful的method表达语义其实是很清晰的,但它和传统的RPC的思维方式并不直接兼容,所以最怕就是半吊子还要硬上rest,最后弄出个四不像。如果一个团队有三成的人理解不了rest怎么写login,那还是放弃他吧,免得挖大坑,GET/POST也是很清晰的语法体系。
所以针对每个项目所达到的目的不同,无法强行决定所有项目都用restful,只能去找到最合适的方案。因为restful用起来比较复杂,甚至有大部分人是不理解并且用不明白的。与其承担漏洞风险,不入强行控制只用POST请求,所以一些公司会出现这种要求。如果这样真能节约成本,提高开发效率。把更多的时间用在比如业务架构设计、测试体系,线上监控、容灾降级等领域上,最终能让员工和企业得到收益,也是没有问题的。
参照
1、业界最佳实践:
- 幂等不修改服务器状态的用GET
- 幂等修改服务器状态的用PUT
- 不幂等修改服务器状态的用POST
2、对于动态业务接口,只有一个接口 POST /action,在Header里给X-Action给出具体的接口名称交给网关路由,session表示用户登录身份,以及用于推荐、防重、染色、安全用到的各种token/签名。所有的业务请求参数都以PB编码后放在请求体里,并和后端的gRPC体系衔接。接口除了防重试之外,不提供常规意义上的Cache。而对于静态接口,走CDN,做多级Cache。该用Get用Get。如果一个动态接口也想利用http层Cache,可以向网关申请和配置。有没有Cache,cache多久是网关和端上自己实施的,完全自己管控。