您的WebService版本最佳实践是什么?

Era*_*dan 19 architecture versioning web-services

我们有2个独立的产品需要通过Web服务相互通信.支持API的自动化的最佳实践是什么?

我从2004年开始这篇文章声称没有实际标准,只有最佳实践.更好的解决方案?你如何解决WS版本问题?

问题描述

系统A.

客户

class SystemAClient{
    SystemBServiceStub systemB;
    public void consumeFromB(){
        SystemBObject bObject = systemB.getSomethingFromB(new SomethingFromBRequest("someKey"));

    }
}
Run Code Online (Sandbox Code Playgroud)

服务

class SystemAService{
    public SystemAObject getSomethingFromA(SomethingFromARequest req){
        return new SystemAObjectFactory.getObject(req);
    }
}
Run Code Online (Sandbox Code Playgroud)

可转让对象

版本1

class SystemAObject{
     Integer id;
     String name;
     ... // getters and setters etc;
}
Run Code Online (Sandbox Code Playgroud)

版本2

class SystemAObject{
     Long id;
     String name;
     String description;
     ... // getters and setters etc;
}
Run Code Online (Sandbox Code Playgroud)

请求对象

版本1

class SomethingFromARequest {
     Integer requestedId;
     ... // getters and setters etc;

}
Run Code Online (Sandbox Code Playgroud)

版本2

class SomethingFromARequest {
     Long requestedId;
     ... // getters and setters etc;

}
Run Code Online (Sandbox Code Playgroud)

系统B.

客户

class SystemBClient{
    SystemAServiceStub systemA;
    public void consumeFromA(){
        SystemAObject aObject = systemA.getSomethingFromA(new SomethingFromARequest(1));
        aObject.getDescription() // fail point
        // do something with it...
    }
}
Run Code Online (Sandbox Code Playgroud)

服务

class SystemBService{
    public SystemBObject getSomethingFromB(SomethingFromBRequest req){
        return new SystemBObjectFactory.getObject(req);
    }
}
Run Code Online (Sandbox Code Playgroud)

可转让对象

版本1

class SystemBObject{
     String key;
     Integer year;
     Integer month;
     Integer day;

     ... // getters and setters etc;
}
Run Code Online (Sandbox Code Playgroud)

版本2

class SystemBObject{
     String key;
     BDate date;
     ... // getters and setters etc;
}

class BDate{
     Integer year;
     Integer month;
     Integer day;
     ... // getters and setters etc;

}
Run Code Online (Sandbox Code Playgroud)

请求对象

版本1

class SomethingFromBRequest {
     String key;
     ... // getters and setters etc;
}
Run Code Online (Sandbox Code Playgroud)

版本2

class SomethingFromBRequest {
     String key;
     BDate afterDate;
     BDate beforeDate;
     ... // getters and setters etc;
}
Run Code Online (Sandbox Code Playgroud)

失败场景

如果系统A 客户端版本1调用系统B 服务版本2也可以在失败:

  • 失踪法SystemBObject(getYear(),getMonth(),getDay())
  • 未知类型 BDate

如果系统A 客户端版本2调用系统B 服务版本1可以在失败:

  • (A客户端使用B版本1无法识别的较新B请求对象)BDate上的未知类型SomethingFromBRequest
  • 如果System A客户端足够智能以使用请求对象的版本1,则它可能会失败,因为对象上缺少方法SystemBObject(getDate())

如果系统B 的客户端版本1调用系统A 服务版本2也可以在失败:

  • 键入missmatch或overflow on SystemAObject(返回Long但是预期Integer)

如果系统B 的客户端版本2调用制度 服务版本1可以在失败:

  • 输入mismatch或overflow on SystemARequest(请求Long代替Integer)
  • 如果请求以某种方式传递,则转换问题(存根是Long但服务Integer在所有WS实现中返回不兼容的nessecarily)

可能的解决方案

  1. 在推进版本时使用数字:例如SystemAObject1,SystemBRequest2但是缺少用于匹配源/目标版本的API
  2. 在签名中,传递XML而不是对象(yuck,在XML中传递转义的XML,双序列化,反序列化/解析,解析)
  3. 其他:例如Document/literal/WS-I有补救措施吗?

Jus*_*ner 23

我更喜欢Salesforce.com版本控制方法.每个版本的Web服务都以以下格式获取不同的URL:

http://api.salesforce.com/{version}/{serviceName}
Run Code Online (Sandbox Code Playgroud)

因此,您将拥有如下所示的Web服务URL:

http://api.salesforce.com/14/Lead

http://api.salesforce.com/15/Lead
Run Code Online (Sandbox Code Playgroud)

等等...

使用此方法,您可以获得以下好处:

  1. 你总是知道你正在和哪个版本交谈.

  2. 保持向后兼容性.

  3. 您不必担心依赖性问题.每个版本都有完整的服务.您只需要确保不要在调用之间混合版本(但这取决于服务的使用者,而不是您作为开发人员).