关于Restful 和JSON-RPC的 一点理解

  • REST要求要将接口以资源的形式呈现。但实际上,很多时候都不太可能将一些业务逻辑看作资源。即使强制这么干了,也会非常非常别扭。登录就是登录,而不是“创建一个session”;播放音乐就是播放,而不是“创建一个播放状态“。
  • REST只提供了增删改查的基本语义,其他的语义基本上不管。比如批量添加,批量删除,修改一个资源的一部分字段。区分“物理删除”和“标记删除”等等。复杂的查询更加不显示,对于像筛选这类的场景,REST明显就是个渣。这里要表扬一下GraphQL(但GraphQL有其他的问题,在此不展开)
  • REST建议用HTTP的status
    code做错误码,以便于“统一”,实际上这非常难统一。各种业务的含义五花八门,抽象层次高低不齐,根本就无法满足需要。比如一个404到底是代表这个接口找不到,还是代表一个资源找不到。400表达请求有问题,但是我想提示用户“你登录手机号输入的格式不对“,还是“你登录手机号已经被占用了“。既然201表示“created”,为啥deleted和updated没有对应的status
    code,只能用200或者204(no
    content)?错误处理是web系统里最麻烦的,最需要细心细致的地方。REST风格在这里只能添乱。
  • web请求参数可能散布在url
    path、querystring、body、header。服务器端处理对此完全没有什么章法。客户端和服务器端的研发之间还是要做约定。
  • 在url path上的变量会对很多其他的工作带来不良影响。

比如监控,本来url可以作为一个接口的key统计次数/延迟,结果url里出了个变量,所以自动收集nginx的access
log,自动做监控项目增加就没法弄了。再比如,想对接口做流量控制的计数,本来url可以做key,因为有变量,就得多费点事才行。

  • 现实中接口要处理的真正的问题,REST基本上也没怎么管。比如认证、授权、流控、数据缓存(http的etag还起了点作用)、超时控制、数据压缩……
  • REST有很多好的工具可以便利的生成对应的代码和文档,也容易形成规范。但问题是REST在实际的项目中并没有解决很多问题,也在很多时候不合用,因此产生的代码和文档也就没什么用,必须经过二次加工才能真的用起来。因此可以基于REST+你的业务场景定义一个你自己的规范。

REST的本意是基于一个架构的假设(资源化),定义了一组风格,并基于这个风格形成约定、工具和支持。思路不错。但是因为他的架构假设就是有问题的,因此后续一系列东西都建立在了一个不稳固的基础之上。
同时,REST并没有解决太多的实际问题。是,的确,有些时候,用REST完成CRUD已经能完成任务了。此时,用REST没有什么不好的。
但是,现实当中,真正的业务领域一般都会比资源的CRUD复杂的多。
这时REST“基本上没解决太多实际问题”的缺点就会体现出来。
我所见到的大多数情况,是会形成一种REST-like形式的接口,像REST却又不限于REST。为了REST,我看到了太多的人在争执到底是POST还是PUT,到底用querystring还是body,到底用200还是201,到底一个单词应该用单数还是复数,到底一个请求参数应该放在url path的中间一段还是最后一段…… 真正要做的事情本身反而没人关心。
现实当中接口的开发的方式你可以总是从REST开始,如果你要开发的东西能被自然而然的想成是一个资源。然后通过相关的工具自动生成一些代码,把这个原型和你的合作者讨论一下。
这是我能想到的REST能做的一件很好的事情——快速实验。
然后如果你想认真的往下做,就可以彻底忘记REST这件事。开始自己定义业务接口,尽量不要在url里加变量。尽量只用GET和POST,减少一些沟通上的混乱。
对于每个接口,好好定义可能发生的业务错误,并与PM一起协商怎么处理这些错误。认真的考虑认证、授权、流控等机制,当你开发的是和钱相关的业务尤其要留意。
最后,本文并不是说“绝对不要用REST”,而是:如果你在实际工作中用REST有了困惑,不知道某个情况下REST此时的最佳实践是什么时,不要追求“真正的REST会怎么做”,不要被REST限制住。

=======
restful首先是要求必须把所有的应用定义成为“resource”,然后只能针对资源做有限的四种操作。
这是对API一个非常糟糕的抽象,有太多现实中需要的API,无法顺当的融入到restful所定义的规范中。
比方说,user login / resetpassword等等。restful的信徒,他们会说可以根据这个那个规范,把login / password等也纳入为某种资源,然后进行增删改查。这在我看来,纯粹是在解决一些原本不存在,根本不需要解决的问题,纯浪费。所有的接口,服务器端原本就存在有相应的函数,它们本来就有自身的命名空间,接受的参数、返回值、异常等等。采用轻便的方式暴露出来即可。
无需把一堆函数重新归纳到“资源”,再削减脑袋把所有的操作都映射为“增删改查”。对应到web上,rpc的成熟方案非常多,有古老的soap,也有轻量的json rpc。JSON rpc基本上仅是要求所有的请求必须有msg id,有函数名,然后可定义参数,并且区分返回值与异常;也可定义『命名空间』来对函数模块做划分。这与大多数语言的模块、函数定义相符,使用起来是非常便利的。很多json rpc是供web前端ajax调用,若前端调用抽象得当,调用远程API,实际上与调用本地函数无甚区别。实际上,json rpc也未必需要跟http绑定,即便是在web上,它也可以走web socket,这样子,前端可以使用同一web socket管道批量发送请求,而服务器端乱序返回结果时,前端也可以根据msg id做准确的回调。websocket,批量调用,乱序返回,这些都可以显著提高API的输出吞吐,这些是在json rpc的设计考量内。调用更方便,性能也更好,两全其美是完全可能的。想当然的为了“快”,为了“简单”就必须牺牲别的,这是严重的思维误区。有些方案,纯粹就是糟糕的方案。restful API仅适用与业务非常简单的场景,比方说,就是为了提供少量数据表单的增删改查。而这种场景实在是太过简单,实际中几乎找不到。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值