什么是你的WebService版本的最佳实践? [英] What are your WebService Versioning best practices?

查看:73
本文介绍了什么是你的WebService版本的最佳实践?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有需要通过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() 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实现兼容)

可能的解决方案


    推进
  1. 使用数字时版本:如 SystemAObject1 SystemBRequest2 等,但,这是缺少匹配源/目标版本的API

  2. 在签名,通过XML而不是对象(呸,传递XML逃脱XML,双串行化,反序列化/解析,unparsing)

  3. 其他:如的确文档/文字/ WS-I有补救措施?


解决方案

我preFER版本的Salesforce.com方法。 Web服务的每个版本都得到了不同的URL格式为:

  http://api.salesforce.com/ {版本} / {}服务名

所以你必须看起来像Web服务网址:

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

等等...

通过这种方法,你得到的好处:


  1. 您总是知道你在说哪个版本。


  2. 向后兼容性得以保持。


  3. 您不必担心依赖问题。每个版本都有一套完整的服务。你只需要确保你不混合调用之间的版本(但这是最高的服务消费者,而不是你的开发者)。


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 the SomethingFromBRequest (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 (returned Long but expected Integer)

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 (request Long instead of Integer)
  • If the request passed somehow, casting issues (the stub is Long but the service returns an Integer not nessecarily compatible in all WS implementations)

Possible solutions

  1. Use numbers when advancing versions: e.g. SystemAObject1, SystemBRequest2 etc but this is missing a an API for matching source / target version
  2. In the signature, pass XML and not objects (yuck, pass escaped XML in XML, double serialization, deserialization / parsing, unparsing)
  3. 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:

  1. You always know which version you're talking to.

  2. Backwards compatibility is maintained.

  3. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆