浅谈WebService的版本兼容性设计

在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform、WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所有这些客户端的需求,实现前后端的分离,一种最常见的做法是,编写WebService API来为以上客户端提供数据。近年来越来越多的企业或者网站支持Restfull方式的WebServiceAPI,比如当当网开源Dubbox,扩展Dubbo服务框架支持REST风格远程调用,这个是Java版本的,在.NET中ServiceStack天生支持Restfull风格的WebService。本文主要以ServiceStack为基础探讨,浅谈WebService的兼容性设计。

1.软件的兼容性

在软件持续更新升级的过程中,API 也是需要不断更新,这时就需要考虑客户端升级以及兼容性的问题。当前有很多用户可能由于多种原因,尤其是Native用户,不可能及时升级到最新版,所以需要提供对老版本的API的向后兼容。在API设计之初,我们需要考虑一些问题以及解决方法。

后向兼容性(Backward_compatibility),或者向下兼容,是指对于给定的输入,较老版本的产品或者技术,也能够输出相同的结果。如果一个产品或者API在设计之初就能够为新的标准考虑,能够满足接收,读取,查看就的标准或者格式,那么这个产品就称之为后向兼容,比如一些数据格式或者通讯协议,在新版本推出时都会充分考虑后向兼容问题。如果对一个产品的改进破坏了后向兼容性,则称之为破坏性的改动(breaking change),相信大家都遇到过这种情况。

  • App长久没更新,落后很多个版本之后,再次打开改App会提示升级到最新版,或者直接帮你强制升级。
  • 使用新版的TortoseVersion打开老版本TortoseVersion创建的工程的时候,会提示需要升级项目工程才能打开。

这种情况一般发生在版本的改动比较大,或者对较老版本的支持成本比较大,在这种情况下,一般还需要为客户提供从老版本迁移到新版本的工具或者解决方案。

兼容性有很多种类型比如 API 的兼容, 二进制dll的兼容性,以及数据文档的兼容。

关于API的兼容性其实涉及到API的设计。相关文档和书籍有很多,关于API设计的书可以参考Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries (2nd Edition)How to Design a Good API and Why it Matters

本文主要探讨WebService开发的API的向后兼容性。

2. WebService 的后向兼容性

在关于开发WebService框架上,这里不免又要谈一下WCF和ServiceStack的设计理念和区别。

在ServiceStack中,鼓励使用Message-based 式的设计,因为远程服务调用是很耗时,我们应该尽量一次多传输需要处理的数据,而避免来回多次调用。在WCF中,通过一些工具,使得开发者能够像调用本地方法一样调用远程方法,这样会使人产生误解,实际上调用远程方法会比调用远程方法慢上成千上万倍。ServiceStack在设计之初就受Martine Flowler 的 Data Transfer Object 模式的启发:

%26ldquo; When you're working with a remote interface, such as Remote Facade (388), each call to it is expensive. As a result you need to reduce the number of calls, and that means that you need to transfer more data with each call. One way to do this is to use lots of parameters. However, this is often awkward to program - indeed, it's often impossible with languages such as Java that return only a single value.

The solution is to create a Data Transfer Object that can hold all the data for the call. It needs to be serializable to go across the connection. Usually an assembler is used on the server side to transfer data between the DTO and any domain objects. %26rdquo;

在API的设计上WCF鼓励将WebService作为普通的C#方法调用,这是一种基于普通的基于PRC 方式的调用。比如:

public interface IWcfCustomerService
{
    Customer GetCustomerById(int id);
    List%26lt;Customer%26gt; GetCustomerByIds(int[] id);
    Customer GetCustomerByUserName(string userName);
    List%26lt;Customer%26gt; GetCustomerByUserNames(string[] userNames);
    Customer GetCustomerByEmail(string email);
    List%26lt;Customer%26gt; GetCustomerByEmails(string[] emails);
}

以上WebService方法就是通过id,username或者email获取用户或者用户列表。如果使用ServiceStack的基于Message-base风格的API设计,接口就是:

public class Customers : IReturn%26lt;List%26lt;Customer%26gt;%26gt;
{
    public int[] Ids { get; set; }
    public string[] UserNames { get; set; }
    public string[] Emails { get; set; }
}

在ServiceStack中,所有的请求信息都包装在这个Customers的DTO中,他并不依赖于服务端方法的签名。最简单的好处在于使用message-base的设计在于wcf中的任意RPC组合都可以使用一个ServiceStack中的远程消息组合,并且只需要服务端的一次实现。

闲话说了这么多,现在来看看如何设计WebService的后向兼容性。谈到WebService,大家都会想到WCF,关于WCF的后向兼容,在Codeproject上,有人写了三篇文章WCF Backwards Compatibility and Versioning Strategies(part1,part2,part3),由于ServiceStack仅支持Poco方式的请求参数,并且写在Poco中的字段都是必须的,没有WCF 中的对字段的 [DataMember(IsRequired = true)] 和 [DataMember(IsRequired = false)] 来标识字段是否可选,所以WCF支持的RPC方式的参数(Part1文章中的后向兼容算法)ServiceStack中无法做测试,这里对比做Part2文章中的测试。并且测试的时候,测试添加和移除字段对Service调用的影响。

建立测试之前,我们先建立一个基本的ServiceStack程序。 这个程序和前文中介绍一样,是一个简单的 ServiceStack序。

3. 基础

使用ServiceStack创建服务,基本的工程结构有三个。

basic servicestack programe

ServiceModel这一层主要是定义 WebService中的请求参数和返回参数DTO, Employ中的代码如下:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值