我正在处理个人项目,客户端桌面应用程序以及处理所有数据库查询的REST API服务器。
这是我的情景。
我有一个高级别的hibernate实体
@Entity
@Table(name="Customer")
public class Customer {
private int id;
private int age;
// getters and setters
}
客户端和服务器将使用相同的持久性类,因为即使它提供REST API,我也是唯一一个在客户端上工作的人。
get Customer的REST API v1响应是
new ResponseEntity<Customer>(article, HttpStatus.OK);
然后客户端将收到Customer json并将其解析回Customer对象。
现在我的问题是,如果客户类发生了变化,说明年龄字段已被删除并且添加了dob字段,我该如何在服务器端管理此更改?
我已经阅读了有关创建版本的文章,但我无法想象如何在这样的情况下完成。 v2将使用最新版本的Customer类,但随后v1将不可用(换句话说,它的响应已更改),因为v1的客户类版本不再存在。有些人建议为每个版本使用不同的软件包,我认为它不合适,因为这意味着使用这些持久性类的所有业务逻辑也必须根据其版本放入不同的软件包中。
我可能使用错误的结构,所以任何建议都非常感谢。
答案 0 :(得分:0)
如果要在两个应用程序之间共享类的子集,通常会将所有这些类打包到一个单独的jar文件中,并在应用程序之间进行交换。
可能的基于Maven的场景将创建一个包含您要共享的类的新项目。每次进行更改时都会提取工件的版本,并mvn install
将其插入工件存储库,例如:关系。现在,您需要提升桌面应用程序和服务器项目中的依赖关系。
当然,还有其他方法,但在单独的模块/项目中隔离共享代码可能是推荐的方法。
答案 1 :(得分:0)
在REST API中公开持久性模型时,版本控制可能会非常棘手。要处理多个版本,您应该针对每个版本的REST API考虑不同的DTO,如answer中所述。
专用REST API模型将带来仅暴露您需要的数据的好处。然后您的控制器或服务可以相应地处理它。
答案 2 :(得分:0)
提供API(网络或其他)的动机之一是使客户端与实施变更隔离。因此,如果您的实现的更改必须闯入API,那么您已经失去了某个地方的情节。
您应该查看的资源
这是韦伯的重要内容
网络不是您的域名,它是一个文档管理系统。所有HTTP谓词都适用于文档管理域。 URI不会映射到域对象 - 这违反了封装。工作(例如:向域模型发出命令)是管理资源的副作用。换句话说,资源是反腐败层的一部分。您应该希望集成域中的资源比业务域中的业务对象多得多。
好的,直到你的问题
我读过有关创建版本的文章,但我无法想象如何在这种情况下完成它。 v2将使用最新版本的Customer类,但随后v1将不可用(换句话说,它的响应已更改),因为v1的Customer类版本不再存在。有些人建议为每个版本使用不同的包,我认为这不合适,因为这意味着使用这些持久性类的所有业务逻辑也必须根据其版本放入不同的包中。
以下是关键思想:“顾客”的语义并没有改变;您的老客户完全有权期望旧的代表将继续工作。因此,集成到您的设计中的第一个想法是,提供不同形状的Customer表示的集成资源是API中的不同资源。
因此,“should”应该是一个返回旧表示的旧端点,以及一个检索新表示的新端点。
第二点是你应该预先在合同中加入一些设计工作(显然,这对于你控制服务器和唯一客户端的练习来说并不重要;但如果这是一个学习练习, 它是)。这意味着,除其他外,要注意了解表示中哪些元素是强制性的,哪些是可选的。
客户只有权期望必填字段存在。可能存在可选字段,但是必须足够强大地编写客户端以处理它们不是的情况(如果服务器不提供默认值,则典型实现将具有默认值)。此外,客户必须期望可能出现新字段,并且必须忽略这些字段。
有时称为弱模式,如果您查看了avro,protocol buffers等详细信息,则应该熟悉此方法。它基本上意味着建立你的表示(消息)设计能力extend it in the future。