几乎所有 API 都在处理不同的发布版本。您经常会看到这种版本控制:
但是我还没有找到描述如何在 Spring 堆栈中组织它们的源。我想在每个控制器上都有一个/v1
前缀并不是最好的方法。@RequestMapping("/v1/questions")
想象一下,有@Service
一层只是当前版本(在我们的例子中是 V2)。
我们的 Service 应该处理 V1 和 V2 的请求。唯一的变化是 V2 在问题实体上添加了一个新字段(这意味着 V1 问题可以轻松转换为 V2 问题)。
现在的问题是:
~.web.* @Controller
从java包的角度如何组织不同的?- 如何注释
~.web.* @Controller
他们知道他们的版本的不同之处?以RequestMapping
? 或者是否可以在 V1 java 包中使用 context:component-scan 配置它们? - 如何组织转换器?放在哪里,如何命名?嗯。像 QuestionsV1ToV2 控制器?
- 是否需要 DTO 层?因为我们的域必须同时处理多个版本?
一个示例可能如下所示(我在各处添加了软件包):
// on V1 Question look like this:
public class project.domain.Question
{
private String question;
}
// on v2 Question looks like this:
public class project.domain.Question
{
private String question;
private Date creationDate;
}
@Service
public class project.service.QuestionService
{
public long create(Question q) {...};
public Question read(long id) {...};
public void remove(long id) {...};
public void update(Question qd) {...};
}
@Controller
@RequestMapping("/v2/question")
public class project.web.v2.QuestionController
{
@Autowired
project.service.QuestionService questionService;
@RequestMapping(method = RequestMethod.POST)
@ResponseBody
public long create(Question q)
{
return questionService.create(q);
}
}
@Controller
@RequestMapping("/v1/question")
public class project.web.v1.QuestionController
{
@Autowired
project.service.QuestionService questionService;
@RequestMapping(method = RequestMethod.POST)
@ResponseBody
public long create(Question q)
{
// this will not work, because the v1 haven't had the 'creationDate' field.
return questionService.create(q);
}
}