为每个实体实现返回不同的属性是否是一种不好的做法?



我正在构建一个 REST API,我有一个实体Contact(接口(,有两个实现:

interface Contact {
val id: String
val email: String
}
class IndividualContact(
override val id: String,
override val email: String
val name: String,
val lastName: String) : Contact
class CompanyContact(
override val id: String,
override val email: String
val tradeName: String) : Contact

我有一个端点"GET/contacts">,它返回所有联系人、个人和公司。因此,响应如下所示:

[
{"id": "1", "name": "John","lastName": "Doe", "email": "john@mail.com"},
{"id": "2", "tradeName": "ACompany", "email": "hello@acompany.com"}
]

如您所见,属性不同。这是一种不好的做法吗?即使我在每个项目中都包含鉴别器属性type,这是一种不好的做法吗?

这是一种不好的做法吗?即使我在每个项目中都包含鉴别器属性类型,这也是一种不好的做法吗?

我不会认为这是一种不好的做法,不一定 - 但它可能是不完整的。

似乎缺少的部分是任何看起来像稳定模式的东西;消费者应该对存在的数据、缺失的数据等做出哪些假设。

例如,在这种情况下,我们的架构可能看起来像

Required: { id: integer, email: string}
Optional-Extension-1 : { name: string, lastName string }
Optional-Extension-2 : { tradeName: string }

以这种方式表示,您具有一组同类属性。 在您的示例中,第一个答案具有RequiredOptional-Extension-1部分,而第二个条目具有RequiredOptional-Extension-2部分。

只要客户清楚地了解他们必须忽略/必须转发他们不理解的可选部分,并且对如果他们期望的部分丢失时该怎么做标准的事情有所了解,您就可以添加(记录(扩展到您的心内容。

Greg Young 的《事件源系统中的版本控制》是一个很好的起点。 您还可以在文档中找到许多标准消息格式(协议缓冲区、Avro 等(的良好提示。

最基本的规则是:不能向现有消息架构添加新的必填字段,也不能更改已定义字段的含义。 (如果需要执行其中任一操作,则完全定义一个新的消息架构(。

相关内容

最新更新