今天眼睛有点痛,早点下班回来,不想做饭,顿觉无聊,掐指一算,还是写点想法吧。写东西也是一个休息吧。就聊一下互联网的应用程序接口吧。


互联网最流行的应用程序接口,莫过于 RPC 与 RESTful。两者的一个重要区别是如何对待客户端,RPC 把客户端视为整个系统的一部分,服务器与客户端之间紧密耦合。而 RESTful 刚好相反,客户端与服务器之间,仅需要一个入口 URL。


国内绝大多数 Api,包括新浪微博之类的 HTTP/JSON Api,都是 RPC,RPC 的一个常见的问题就是接口的管理问题。由于它与客户端耦合起来,与客户端共同组成一个系统,因此只要业务有变化,就会导致两端都要变化,有时候这种变化是灾难性的。比如看上去是系统的升级,却实际是一个系统的完全重写。更多的做法是使用接口版本的概念,这又会引用版本管理的问题。版本只能让旧的客户端继续正确的工作,却无法使用新的 Api,除非客户端也升级。


RPC 的每个接口都是独立(这不是说它无状态的)的,就需要每个接口都要有文档。文档管理又是 RPC 的另外一个问题。程序员在写文档的时候心中千万语一笔带过,而使用缺少文档的接口时,口中又有千万个草泥马。哈哈,都中招了有木有?


另一种接口就是 RESTful 接口,近几年非常火,而领会它的精髓的人却又寥寥无几。国内互联网上绝大多数自称为 RESTful 接口,都不 RESTful, 包括我自己以前写的接口,都只是 RPC 而已。其实 REST 在 15 年前,就已经出现在我们身边,世界规模最大、最地道、最成功的 REST,就是我们每天浏览的 Web。要认识 REST,只要认识 Web 就可以了。


完全的 RESTful 接口,是不需要文档的。有人为 Web 写过文档吗?文档本身就是 Web !目前移动互联网的兴起,很多所谓的 HTML5 写的单页面无刷新 App,使用 Javascrpt 来做数据与页面模板的交互,本质是 RPC,对于一个 Web 应用来讲,实际是技术与架构的退化。


那什么是 REST,什么是 RESTful 接口呢?REST 是一组架构风格的总称,内涵非常丰富,猿类自行 Google,Roy Fielding 那篇博士论文是必读的大作。符合 REST 风格的接口,称为 RESTful 接口。我无法将 REST 描述出来,只有通过一些特征,一窥 REST  真容。


HTTP 协议,是实现 REST 的最完整、最成功的,几乎是唯一的协议。换句话说,HTTP 是专为 REST 实现的唯一广泛使用的协议。


HTTP 是应用层的协议,无需在其上附加其它协议。而 RPC 将 HTTP 视为传输层协议或通道,如 WSDL、Thrift 等。


REST 有三大组件:接口动词、资源名词、资源表述,就是 HTTP 定义的方法,URI,超媒体。


HTTP定义的方法,就是统一的接口,如 GET、POST、PUT、DELETE、HEAD、OPTIONS。这些方法有两个属性:安全性与幂等性。这两个属性是正确使用统一接口的依据,而不是所谓的 CRUD (创建、读取、更新、删除)。


安全性是指会不会对资源造成破坏。比如读取一个资源,是不会对资源造成破坏的。而更新或删除,则会破坏资源的状态,让资源变成另一个状态,所以称为不安全。


幂等性是指对同一个资源做多次相同的操作,其作用的效果与一次操作的效果是否相同。比如读取资源 1 次与 N 次,其效果是一致的。这称为幂等。


庞大复杂的互联网基础设施(比如网关、代理、缓存等),正是依据统一接口运作的。


第二个组件就是 URI,它是指示资源位置或者资源名称的名词。


第三个组件就是超媒体。资源与资源之间的联系,是通过由 URI 构造的连接以及连接的关系进行的。连接是超媒体最重要的组成部分。最典型的超媒体莫过于 HTML。


试想一下 Web 服务器与浏览器,服务器提供的服务千差万别,丰富多彩,但是服务器的任何变化,什么时候要求浏览器去适应它?服务器提供的资源与服务的升级,什么时候要求重写浏览器?理解了这一点,就了解了 REST 的关键点:超媒体驱动的应用程序状态转移!


所以,RESTful 接口的一个重要特点是:客户端只需要知道一个入口 URI(或者收藏夹里的 URL),就能完成一个系统、一个应用程序的所有的状态转移(即完成所有的业务)。符合这一点,你的接口才有资格称为 RESTful 接口。


试想这样的接口,还需要接口管理与文档吗?还不明白,就想想 Web Page 吧!


哦,发现写了这么多,还没涉及 REST 的二十分之一。本文还有很重要的内容协商、可见性、缓存、性能、URI 模板、并发与乐观锁、认证与受权等很多方面没涉及。先不写了,下次有兴致再说……