我们公司有一个网络产品,它提供了近 160 种不同的 REST API 来与我们的产品进行交互。目前,API 仅供内部客户端产品使用,但最终会公开。我正在编写 ac# 包装器以使用 RestSharp 库调用这些 REST API,到目前为止一切正常。例如,获取账户信息的 GET API 之一是:
/api/account/{id}
它返回 JSON 数据,如:
{ “Id” : “12345”, “Name” : “Test Account” }
收到数据后,我只是将 JSON 字符串反序列化为适当的 DTO 并返回对象。所以,我在 API 包装器中的功能是:
Public Account GetAccount ( int accountId )
{
//create restsharp client and request
return restClient.Execute<Account> ( restRequest )
}
但是,现在的问题是 API 正在发生变化。我们正在引入新版本的 API。在较新的版本中,端点保持不变,唯一的区别是它们返回不同的数据。
比如V1获取账号的API是:(如果没有设置版本,默认服务器会使用V1)
GET - /api/V1/account/{id}
它返回 JSON 数据,如:
{ “Id” : “12345”, “Name” : “Test Account” }
获取帐户的 V2 API 是:
GET - /api/V2/account/{id}
它返回 JSON 数据,如:
{ “Id” : “12345”, “Name” : “Test Account”, “Company” : “Some Company”, “Status” : “Some Status” }
将来,相同 API 的较新版本可能会返回不同的数据。此外,即使 API 的版本发生变化,并非所有更新版本的 API 都会发生变化。如此多的 API 将继续发送 V1 对象数据。与 V1 版本相比,只有一定数量的 API 会发送不同的数据。
现在我的困境是如何重构现有的 API 包装器:
- 第一种方法是为每个新版本的 API 创建新方法。例如:
Public AccountV1 GetAccountV1 ( int accountId )
- 它将调用 V1 api 并将 JSON 反序列化为 V1 对象并返回它;并且,Public AccountV2 GetAccountV2 ( int accountId )
- 它将在 URL 中调用与 V2 相同的 API,并将 JSON 反序列化为 V2 对象并返回它。
这种方法的问题在于——我必须重写几乎相同的代码来为 160 个 API 创建 V2 函数。此外,如果有更新版本的 API 出现,我将不得不再次做同样的事情 - 为 V3 重写 160 个方法。
- 其次是使用泛型、抽象工厂、动态代理或其他设计,这样我就不必为不同版本的 API 重写几乎相同的代码
对于第二种方法,我不确定如何实现它。我的目标是重构我的包装器代码,以便需要最少的代码更改,它是可扩展的——这意味着,如果我们更改 API 版本和返回的数据,我以后不必再次重写大量的东西。
在重构我的代码和帮助我选择正确的设计模式方面的任何帮助都会非常有帮助。任何示例都会有所帮助。