请求--响应类的API的典型做法是,通过基于HTTP的Web服务器暴露一个/套接口。API定义一些端点,客户端发送数据的请求到这些端点,Web服务器处理这些请求,然后返回响应。响应的格式通常是JSON或XML。
在这种类型的Web API里,比较流行的是这三种:REST,RPC和GraphQL。
REST全称是Representational State Transfer 表述性状态传递。REST可能是现在最流行的一种Web API。
REST的核心就是资源,一个资源就是可以被标识的实体,它有名称和地址。
REST API就是把数据以资源的形式暴露出来,并使用标准的HTTP方法来代表创建、读取、更新和删除资源等事务。
REST API有一些规则和约束,这里我就简单的写一下(之前的文章有详细描述):
如果两个资源有主从关系,那么子资源最好不采用顶级资源的URL,而是采用主资源的子资源URL地址。例如Province和City就是主从关系,那么City资源的URL应该是:/provinces/{provinceId}/cities,/provinces/{provinceId}/cities/{cityId}
非CRUD操作
API难免会有一个非CRUD的操作,例如“存档”这个操作。这时候我们可以采取以下几种办法:
Remote Procedure Call。RPC是一种比较简单的API,客户端直接会执行另一个服务器上的代码。
REST是关于资源的,而RPC就是关于动作的。
在RPC里,客户端通常是把方法名和参数传递给服务器,然后服务器返回JSON或XML。
RPC的规则比较少:
RPC适用于那种无法用CRUD封装的动作,或者其影响和资源无关的动作。
RPC不仅限于HTTP,还有其它协议可以支持,例如Apache Thrift和gRPC。
GraphQL 是 API的查询语言。最近越来越火。它由Facebook于2012年开始开发,2015年被开源了。
GraphQL允许客户端定义需要得到的数据结构,服务器精确的返回所需的数据结构,例如:
与REST和RPC不同,GraphQL API只需要一个端点;它也不需要使用不同的HTTP动词,它只使用POST,你需要在JSON body里面指定是要执行查询还是修改。
相对REST和RPC,GraphQL有下面几个优势:
GraphQL的缺点就是它为服务器添加了许多复杂性,服务器需要额外的工作来处理这些复杂的查询。根据查询内容的不同,性能也是一个变数.
针对用请求-响应式API,如果服务的数据经常变化,那么响应就可能无法保持新鲜了。开发者如果想与变化的数据保持同步,就只能对API进行polling操作了。
但是如果poll的频率较低,客户端仍有可能无法获得从上次poll到现在所有的数据事件。如果poll的频率较高,还特别浪费资源。
所以我们需要实时的分享事件的数据,通常使用下面三种机制:WebHook,WebSocket,HTTP Streaming。
WebHook就是一个接收HTTP POST(或GET,PUT,DELETE)的URL。一个实现了WebHook的API提供商就是在当事件发生的时候会向这个配置好的URL发送一条信息。与请求-响应式不同,使用WebHook,你可以实时接受到变化。
下面是Polling和Webhook的比较:
WebHook非常适合于从一个服务器向另外一个服务器分享实时数据。
但是实现WebHook,也引入了新的复杂性:
WebSocket这个协议,它通过一个TCP协议建立一个双向全双工的流式通信。WebSocket通常用在客户端和服务器之间的通信,也可以用在服务器之间的通信。
ASP.NET Core SignalR就是优先使用该协议。
WebSocket支持全双工(服务器和客户端可以同时双向通信),而且开销不高。经常使用的端口式80或443,这样就很容易穿过防火墙了。
WebSocket特别适合于快速的,现场的路i数据和长连接。
如果连接挂掉了,客户端会尝试重新初始化连接。但是WebSocket有一些扩展性的问题,因为如果在线的客户端太多,那么服务器端就需要维持这些客户端打开的连接。
使用请求-响应式API,客户端发送一个请求,服务器端返回一个响应,这个响应的长度是有限的。
而使用HTTP Streaming,服务器端可以在一个由客户端打开的长生存的连接里持续的推送新数据。
为了让数据通过一个可长时间存在的连接上进行传输,有两个方案:
HTTP Streaming用起来好像很容易,但是有个问题,是关于缓存的。客户端和代理经常会有缓存的限制。因为只有达到某个阈值之后,它们才会把数据渲染给应用。