6

编写 RESTFul api 应用程序的最佳实践之一是添加版本控制。例如:

http://my-server/api/v1/getData
http://my-server/api/v2/getData

我们的应用程序使用 Spring 框架公开 REST api。我们将一个类标记为 Controller,使用 RequestMapping 注解将 URL 映射到一个函数,并添加一些转换为/从 json 对象转换的对象。

例如:

@RequestMapping(method = RequestMethod.POST, value = "/api/v1/getData")
public @ResponseBody ResponseDataDTO getData(@RequestBody OperationsDetailsTDO details) {...}

现在,我们要提供 API 的第二个版本。大约 2/3 的功能保持不变,而 1/3 的功能正在改变。更改在逻辑和 JSON 对象中。

我想知道如何设计代码。我认为这种代码很难管理:

@RequestMapping(method = RequestMethod.POST, value = "/api/{version-var}/getData")
public @ResponseBody ResponseDataDTO createReleaseFromTemplate(@PathVariable("version-var") Integer version, @RequestBody OperationsDetailsTDO details) {
if (version == 1)
{
   doForVersion1();
}
else if (version == 2)
{
   doForVersion2();
}

}

这将很难管理,因为在每个功能中都会有不同的分支。只是为了演示这个问题,如果我有一个生成文档的自动工具——它将无法理解 API 是什么。

其次,我想知道我应该如何处理绑定到 JSON 对象的类。我是否需要复制所有这些类以进行细微更改?

谢谢。

4

2 回答 2

1

我同意你将版本作为参数传递,就像

@RequestMapping(method = RequestMethod.POST, value = "/api/{version-var}/getData")

但是我认为添加很多分支不是一个好主意,我们应该将资源类中的所有方法提取到业务接口中,例如,

private IDataRetrieve dataRetriever;
@RequestMapping(method = RequestMethod.POST, value = "/api/{version-var}/getData")
public @ResponseBody ResponseDataDTO createReleaseFromTemplate(@PathVariable("version-var") Integer version, @RequestBody OperationsDetailsTDO details) {
    dataRetiever = DataRetrieverFactory.getDataTrieverByVersion(version);  //TODO, create a factory to get DataRetriever
    return dataRetiever.getData();
}

然后你需要两个类来实现 IDataRetriver,(一个用于 V1,另一个用于 v2);当然,为避免重复代码,您可以为 V1 和 V2 添加一个抽象类,并使用模板模式删除重复代码。

于 2013-05-22T14:07:13.647 回答
0

如果您使用版本的路径变量,则可以在 RequestMapping 中使用正则表达式(例如,请参见此处)。或者,您可以创建一个新方法,该方法只调用旧方法,但具有 v2 的较新 RequestMapping。或者,创建一个通用方法来获取版本并调用实际处理该版本请求的正确方法。最后一种方法的好处:如果他们发送的版本不受支持,您可以获取版本并将用户发送到特定错误,例如如果他们发送 /app/v10/whatever。

于 2013-05-22T13:44:38.643 回答