面向资源的设计 - 服务 API 设计方法对比分析

面向资源的设计 - 服务 API 设计方法对比分析

2020级中山大学数据科学与计算机学院 非全班 冯维

1 摘要
        互联网经济不断飞速发展促使计算机技术迅速变革,今天人们越来越享受各大公司提供的互联网服务,云平台的存储、应用、办公等服务也进入了日常生活。全球信息公司纷纷向云计算靠拢,将其作为信息技术未来发展的重点战略,如今云计算已然成为了真正意义上继互联网兴起、计算机普及后第三次互联网革命。
        随着近年来对云计算平台(简称云平台)相关技术的研究,国内云平台技术迅速提高,目前国内已经研发了一系列高性能、安全、可靠的云平台系统。云平台的如今主流架构模式为SOA(Service-Oriented Architecture,面向服务的体系架构)架构思想[1],对软件应用等服务进行重新的封装。过去传统云平台系统架构的实现主要借助SOAP Web Service技术提供Web服务[2]。简单对象访问协议(SOAP,Simple Object Access Protocol)[2]早期作为一种传输协议是提供 Web服务的一种技术,兼容HTTP等一类传输协议。SOAP 随着WS一类协议[3]的不断改进,SOAP的完善度得到提高,但是也导致SOAP协议负担加重,如今对于如何满足用户个性化需求也越来越困难。为此,满足不同场景的API设计方法应运而生。API设计模式主要分为请求-响应和事件驱动,将在第2节详细对比分析这两类API设计模式所对应的设计方法,分析比较它们各自的优缺点和适用场景。

2 各API设计方法比较
        基于请求-响应设计模式的主要有REST、gRPC和GraphQL等,基于事件驱动设计模式的主要有Webhooks、WebSocket和HTTPStreaming等。表2-1分别对上述的API设计方法的特点和适用场景进行了对比。

表 2-1各API设计方法对比

API设计模式
API设计方法特点适用场景
请求-响应REST
(1) 一种体系结构,应用无状态设计理念和构建Web API的标准化方法;
(2) 以无状态的方式与文本化的资源表述进行交互,交互的过程采用GET、POST、PUT和其他HTTP方法作为标准化定义;
(3) 将一切网络资源进行唯一的URI定位;
(4) 分层架构,高效缓存,高可伸缩性等;
(5) 标准化HTTP表达,为终端用户提供了上下文,并使大多数交互标准化。
       REST本质上关心无状态的资源管理,因此也更适用于这种场景。
       需要快速迭代和标准化HTTP表达的系统更适合采用REST。
gRPC
(1) 对历史悠久的RPC(远程过程调用)的一种新的传承;
(2) 用于请求数据的灵活而轻量级的系统 ;
(3) 是RPC概念的进一步发展,并增加了广泛的特性。其中最重要的特性是ProtoBufs;
(4) 通过Google的基于令牌的系统调用SSL/TLS协议,gRPC建立了非常有效和强大的身份验证系统。
       更适用于系统需要对一定量的数据进行例行处理的情况下,发出数据请求的客户端要么是低功耗的,要么是资源苛刻型的,例如物联网。
GraphQL
(1) 一种用户可以自定义所需数据和格式的方法;
(2) 提供了大量的扩展功能;
(3) 客户端和数据之间的新型关系。
       请求者需要特定格式的数据来进行特定的使用。
事件驱动
Webhooks
(1) 一种完全不同的提供资源的方法;
(2) 事件发生时触发的HTTP POST请求;
(3) 服务器更新所需提供的资源,然后自动将其作为更新发送到客户端(服务器是在推数据),客户端不是请求者,而是被动接收方。
       如果API主要用于进行服务器间的实时事件通信。
WebSocket
(1) 通过一个TCP协议建立一个双向全双工的流式通信。
       主要用于服务器之间的双向实时通信
HTTPStreaming
(1) 服务器端可以在一个由客户端打开的长生存的连接里持续的推送新数据。
        需要使用简单的HTTP进行单向通信,可以使用HTTP Streaming

(1)REST
        由Roy提出[4]的REST(Resource Representational State Transfer)表示为表述性状态转移,其中:
         Resource:表示资源,而从程序角度即是数据;
        Representational:表现形式,如常用的传输类型比如TXT、HTML、JSON、XML、JPEG等;
        State Transfer:状态变化,对应的是HTTP协议中的动词(常用的动词如:GET POST PUT PATCH DELETE)。
        REST基于HTTP,所以也是无状态的,以HTTP的各种动词来定义约定一系列的URL来操作资源;它描述的是网络中client与server的一种交互形式。基于REST的网络接口设计风格即是RESTful API,常用的几个最基础RESTful API的URL如下:
 GET /api/users : 列出所有用户
 POST /api/users : 新建一个用户
 GET /api/users/ID : 获取一个用户的指定信息
 PUT /api/user/ID : 更新某个指定用户的信息(全部信息)
 PATH /api/users/ID :更新某个指定用户的信息(部分信息)
 DELETE /api/users/ID : 删除某个用户
         基于RESTful API设计的URI使用的基本都是名字,具体动词其实是依赖HTTP中的各个动词来指定不同的动作(这也是在设计RESTful API时容易产生误用的地方,会把动词放在URI上);
         REST的优点:客户端与服务器分离,简化服务器逻辑以及提高可伸缩性;无状态,降低服务器资源使用(相对于有状态的长连接),同时提高服务器的可扩展性;由于不同的信息返回时可以分开标记是否可以缓存,使得客户端可以重用之前的信息,减少客户端与服务端的交互次数。
(2)gRPC
         RPC-- Remote Procedure Call(远程过程调用),主要是用于服务器之间的方法调用。RPC的本质是提供轻量无感知的跨进程通信方式,与上面基于HTTP的RESTful API并不是对立的,并且应用的场景也有所区别;http的接口优点是简单、直接、开发方便,利用现成http协议进行传输;相对于RPC,如果是基于TCP协议的长连接,不必每次都像http 一样3次握手,减少网络开销;其次一般rpc框架都有注册中心、监控管理,对于服务化架构和服务化治理,RPC框架是 一个强力的支撑;RPC低耗、高效的服务调用方式比较适合 IOT 等对资源、带宽、性能敏感的场景。
         常用的一些分布式RPC框架有Dubbo、Thrift、RPCx等;目前最受关注的是谷歌开源的一个rpc框架:gRPC。gRPC相对于常用的RPC框架最大的特点是使用了protobufs作为语言格式化数据,进一步提高了序列化和反序列化的速度,同时降低数据包的大小[5]。protobuf开源已久,它提供了一种灵活、高效、自动序列化结构数据的机制,作用与XML、JSON等格式类似,但是使用二进制传输,序列化/反序列化的速度快,压缩效率高;而且Protobuf有强大的IDL(Interface Description Language,接口描述语言)和相关的工具,用户写好.proto描述文件之后可以编译成多种语言。gPRC另外一个特点是使用HTTP2,其采用新的二进制格式、多路复用、header压缩,因此其性能远优于HTTP1.1。
(3)GraphQL
         GraphQL是一种针对API的查询语言也是一个满足数据查询的运行时[6]。可以理解为另外一个种客户端与服务器之间的交互方式:前端决定后端的返回结果。它的好处是精简响应的内容,不会出现冗余字段,前端需要什么就取什么,而不需要重新定制开发api。GraphQL并不是REST的替代品,它可以跟REST共存,甚至可以共同使用一些公共授权验证模块验证调用合法性。GraphQL与其它几种API设计的关系如图2-1所示。实现了GraphQL标准的客户端有很多,比如Relay或者appollo-client等。

在这里插入图片描述

(4)Webhooks
         GraphQL是REST的补充,改变了前后端的交互模式,gRPC快速、 高效的方式赋予了客户端更强大的能力,那么webhook可能跟之前的这些方式改变得更彻底,客户端不再主动发送请求,而是完全由后端进行推送,可以说webhook是传统client-server模式彻底的反模式了。
比如客户端要长期监听某个任务的状态,如果按照正常的api调用的方式去做,那么必须不停得轮训服务器来获取当前状态;使用Webhooks则无需轮训,只需要等待服务器推送信息过来,客户端更新即可。git webhook其实也是这方面的应用。

3 小结
         并没有哪种方法是必然优于另外一种的,每一种方法都有其适用的场景。
         REST: 无状态的数据传输,适用于通用、快速迭代和标准化语义的场景;虽然 RESTful API的设计风格是目前最普遍的方式,但是其实也并不是所有场景都适合, 比如遇到有复杂操作要求的前端交互,用起来就很别扭,像获取、删除多个对象;对于一些内部的系统,大多数开发更注重效率,而不是完全遵守这样的规范,真正完全遵守的场景确实也不多。
         gRPC:对于前端跟服务器端交互来说HTTP 无状态的方式其实是最方便的,前后端完全解耦,系统更容易扩展。而对于一些服务端之间的通信,比如现在的微服务,大部分共用服务可能并不需要对外开放,只在内部进行相互调用,这种情况下gRPC是个不错的选择,而且也能满足服务器之间调用对性能和延时要求高的需求。
         GraphQL:GraphQL 并不是作为REST的替代方案,如果指望使用GraphQL能答复提升开发效率,那可能不现实;其实让客户端来选择返回的内容增加了客户端的工作量,把服务器端的一些工作转移出去了。不过相对于那些相对成熟的对外开放的OpendAPI,GraphQL更合适,比如github api,可以让开发者觉得获取内容其实是非常高效的,因为对于稳定的内容,有选择的去获取数据比全量返回从效率上能提升不少。
         Webhook:其实从字面上理解这种应用场景就是需要服务器主动推送的地方,比如没有前端界面作为中转的服务,或者是不适合前端来操作的强安全页面(如支付),算是在特殊场景下的应用方式,毕竟相对于无状态的方式,维持连接来做推送还是开销不小,会增加不少的服务器端压力。
         在技术选型上可能是一个项目开始的时候最艰难的事,不同的应用场景要选择不同的技术解决 方案,毕竟在软件开发上没有银弹,合适的才是最好的。

4 参考文献
[1] Memeti A, Selimi B, Besimi A, Cico B. A framework for flexible REST services: Decoupling authorization for reduced service dependency[C]. 2015 4th Mediterranean Conference on Embedded Computing (MECO), 2015, IEEE: 51-55.
[2] Wilde E. Managing a RESTful SOA: Providing guidance for service designers and orientation for service consumers [J]. it-Information Technology, 2014, 56(3):98-105.
[3] Markey P, Clynch G. A performance analysis of ws-*(soap) and restful web services for implementing service and resource orientated architectures [J]. The IT&T, 2013:93.
[4] Fielding RT, Taylor RN. Architectural styles and the design of network-based software architectures[M]: University of California, Irvine Irvine, 2000.
[5] 王兵.面向ODL 网络控制器集群高性能分布式锁的研究与实现[D]. 南京: 东南大学, 2017.
[6] Nogatz F, Seipel D. Implementing GraphQL as a query language for deductive databases in SWI-prolog using DCGs, quasi quotations, and dicts[J]. arXiv preprint arXiv:1701.00626, 2017.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值