什么是你的WebService版本的最佳实践? [英] What are your WebService Versioning best practices?
问题描述
我们有需要通过Web服务相互连通2个独立的产品。
什么是最好的做法,支持的API versioining?
我有从2004年声称没有实际的标准,只有最好的这篇文章实践。没有更好的办法?你怎么解决WS版本?
问题说明
系统A
客户端
类SystemAClient {
SystemBServiceStub系统B;
公共无效consumeFromB(){
SystemBObject bObject = systemB.getSomethingFromB(新SomethingFromBRequest(someKey)); }
}
服务
类SystemAService {
公共SystemAObject getSomethingFromA(SomethingFromARequest REQ){
返回新SystemAObjectFactory.getObject(REQ);
}
}
Transferable对象
的版本1 的
类SystemAObject {
整数ID;
字符串名称;
... // getter和setter方法等;
}
的 2版的
类SystemAObject {
龙ID;
字符串名称;
字符串描述;
... // getter和setter方法等;
}
请求对象
的版本1 的
类SomethingFromARequest {
整数requestedId;
... // getter和setter方法等;}
的 2版的
类SomethingFromARequest {
龙requestedId;
... // getter和setter方法等;}
系统B
客户端
类SystemBClient {
SystemAServiceStub系统A;
公共无效consumeFromA(){
SystemAObject aObject = systemA.getSomethingFromA(新SomethingFromARequest(1));
aObject.getDescription()//点失败
//用它做什么?
}
}
服务
类SystemBService {
公共SystemBObject getSomethingFromB(SomethingFromBRequest REQ){
返回新SystemBObjectFactory.getObject(REQ);
}
}
Transferable对象
的版本1 的
类SystemBObject {
字符串键;
整年;
整月;
整日; ... // getter和setter方法等;
}
的 2版的
类SystemBObject {
字符串键;
BDate日期;
... // getter和setter方法等;
}类BDate {
整年;
整月;
整日;
... // getter和setter方法等;}
请求对象
的版本1 的
类SomethingFromBRequest {
字符串键;
... // getter和setter方法等;
}
的 2版的
类SomethingFromBRequest {
字符串键;
BDate afterDate;
BDate beforeDate;
... // getter和setter方法等;
}
失败场景
如果一个系统A 客户端版本 1 调用系统B 服务的版本2 它可以在失败:
- 在
SystemBObject
(得到年()
,的getMonth()$缺少方法C $ C>,
getDay()
) - 未知类型
BDate
如果一个系统A 客户端版本 2 调用系统B 服务的版本1 它可以在失败:
- 未知类型
BDate
在SomethingFromBRequest
(客户端使用较新的乙请求对象是B版1没有按' ŧ认识) - 如果系统客户端是足够聪明的使用请求对象的1.0版本,它可能会失败在
SystemBObject
对象上缺少方法(GETDATE()
)
如果一个系统B 客户端版本 1 调用的系统A 服务的版本2 它可以在失败:
- 类型missmatch或溢出
SystemAObject
(返回龙
,但预期整数
)
如果一个系统B 客户端版本 2 调用的系统A 服务的版本1 它可以在失败:
- 类型missmatch或溢流
SystemARequest
(要求整数
) - 如果请求以某种方式传递,铸造问题(存根
龙
,但服务返回整数
不nessecarily在所有的WS实现兼容)
在
可能的解决方案
- 使用数字时版本:如
SystemAObject1
,SystemBRequest2
等,但,这是缺少匹配源/目标版本的API - 在签名,通过XML而不是对象(呸,传递XML逃脱XML,双串行化,反序列化/解析,unparsing)
- 其他:如的确文档/文字/ WS-I有补救措施?
推进
我preFER版本的Salesforce.com方法。 Web服务的每个版本都得到了不同的URL格式为:
http://api.salesforce.com/ {版本} / {}服务名
所以你必须看起来像Web服务网址:
http://api.salesforce.com/14/Leadhttp://api.salesforce.com/15/Lead
等等...
通过这种方法,你得到的好处:
-
您总是知道你在说哪个版本。
-
向后兼容性得以保持。
-
您不必担心依赖问题。每个版本都有一套完整的服务。你只需要确保你不混合调用之间的版本(但这是最高的服务消费者,而不是你的开发者)。
We have 2 separate products that need to communicate with each other via web services. What is the best-practice to support versioining of the API?
I have this article from 2004 claiming there is no actual standard, and only best practices. Any better solutions? How do you solve WS versioning?
Problem Description
System A
Client
class SystemAClient{
SystemBServiceStub systemB;
public void consumeFromB(){
SystemBObject bObject = systemB.getSomethingFromB(new SomethingFromBRequest("someKey"));
}
}
Service
class SystemAService{
public SystemAObject getSomethingFromA(SomethingFromARequest req){
return new SystemAObjectFactory.getObject(req);
}
}
Transferable Object
Version 1
class SystemAObject{
Integer id;
String name;
... // getters and setters etc;
}
Version 2
class SystemAObject{
Long id;
String name;
String description;
... // getters and setters etc;
}
Request Object
Version 1
class SomethingFromARequest {
Integer requestedId;
... // getters and setters etc;
}
Version 2
class SomethingFromARequest {
Long requestedId;
... // getters and setters etc;
}
System B
Client
class SystemBClient{
SystemAServiceStub systemA;
public void consumeFromA(){
SystemAObject aObject = systemA.getSomethingFromA(new SomethingFromARequest(1));
aObject.getDescription() // fail point
// do something with it...
}
}
Service
class SystemBService{
public SystemBObject getSomethingFromB(SomethingFromBRequest req){
return new SystemBObjectFactory.getObject(req);
}
}
Transferable Object
Version 1
class SystemBObject{
String key;
Integer year;
Integer month;
Integer day;
... // getters and setters etc;
}
Version 2
class SystemBObject{
String key;
BDate date;
... // getters and setters etc;
}
class BDate{
Integer year;
Integer month;
Integer day;
... // getters and setters etc;
}
Request Object
Version 1
class SomethingFromBRequest {
String key;
... // getters and setters etc;
}
Version 2
class SomethingFromBRequest {
String key;
BDate afterDate;
BDate beforeDate;
... // getters and setters etc;
}
Fail Scenarios
If a System A client of version 1 calls a System B service of version 2 it can fail on:
- missing methods on
SystemBObject
(getYear()
,getMonth()
,getDay()
) - Unknown type
BDate
If a System A client of version 2 calls a System B service of version 1 it can fail on:
- Unknown type
BDate
on theSomethingFromBRequest
(A client uses a newer B request object that B version 1 doesn't recognize) - If the System A client is smart enough to use version 1 of the request object, it can fail on missing methods on the
SystemBObject
object (getDate()
)
If a System B client of version 1 calls a System A service of version 2 it can fail on:
- Type missmatch or overflow on
SystemAObject
(returnedLong
but expectedInteger
)
If a System B client of version 2 calls a System A service of version 1 it can fail on:
- Type missmatch or overflow on
SystemARequest
(requestLong
instead ofInteger
) - If the request passed somehow, casting issues (the stub is
Long
but the service returns anInteger
not nessecarily compatible in all WS implementations)
Possible solutions
- Use numbers when advancing versions: e.g.
SystemAObject1
,SystemBRequest2
etc but this is missing a an API for matching source / target version - In the signature, pass XML and not objects (yuck, pass escaped XML in XML, double serialization, deserialization / parsing, unparsing)
- Other: e.g. does Document/literal / WS-I has a remedy?
I prefer the Salesforce.com method of versioning. Each version of the Web Services gets a distinct URL in the format of:
http://api.salesforce.com/{version}/{serviceName}
So you'll have Web Service URLs that look like:
http://api.salesforce.com/14/Lead
http://api.salesforce.com/15/Lead
and so on...
With this method, you get the benefits of:
You always know which version you're talking to.
Backwards compatibility is maintained.
You don't have to worry about dependency issues. Each version has the complete set of services. You just have to make sure you don't mix versions between calls (but that's up to the consumer of the service, not you as the developer).
这篇关于什么是你的WebService版本的最佳实践?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!