REST API中的多态设计:基于字段值返回不同数据类型
医疗观测资源REST API建模的常见实现模式
问题背景
我维护的REST API包含Observation资源,该资源有observationType和observationValue两个核心属性:
observationType的有效值包括HEART_RATE、BLOOD_PRESSURE、ORTHOSTATIC_BLOOD_PRESSURE、BODY_WEIGHT;- 不同类型对应不同的
observationValue数据类型:HEART_RATE对应整数BODY_WEIGHT对应浮点数BLOOD_PRESSURE对应包含收缩压、舒张压的对象
示例数据如下:
{ "observationType": "HEART_RATE", "observationValue": 90 } { "observationType": "BODY_WEIGHT", "observationValue": 81.5 } { "observationType": "BLOOD_PRESSURE", "observationValue": {"systolicBloodPressureValue": 120, "diastolicBloodPressureValue": 80} }
想了解业内常见的建模方式,以及是否应该将observationValue统一返回为String类型,同时担心REST API的多态设计会带来混乱。
业内常见实现方式
1. 动态多态的observationValue
这是医疗领域API中最常见的模式之一,直接按照观测类型返回对应数据类型的observationValue(如示例所示)。类似FHIR标准里的Observation资源,通过类型标识指定观测类型,用动态字段存储对应值。
- 优点:数据结构直观,客户端无需额外转换就能拿到原生类型数据;
- 缺点:对Java、C#这类强类型客户端不够友好,需要手动做类型判断与转换,容易出现解析错误。
2. 拆分明确的类型专属字段
将observationValue拆分为多个具体字段,每个观测类型仅返回对应字段,其他字段为null或不返回。示例:
{ "observationType": "HEART_RATE", "heartRateValue": 90 } { "observationType": "BLOOD_PRESSURE", "bloodPressureValue": {"systolic": 120, "diastolic": 80} }
- 优点:强类型客户端适配友好,无需处理动态类型;
- 缺点:资源结构会随新增观测类型不断膨胀,不符合开闭原则,维护成本高。
3. 统一结构化包装对象
不管观测类型是什么,都返回一个包含所有可能值的包装对象,仅填充对应类型的字段,其余留空。示例:
{ "observationType": "HEART_RATE", "observationValue": { "integerValue": 90, "floatValue": null, "bloodPressure": null } }
- 优点:结构一致性强,客户端无需处理动态类型,仅需读取对应子字段;
- 缺点:返回数据存在冗余空字段,不够简洁。
4. 统一返回String类型
将所有observationValue转换为字符串返回,比如心率"90"、体重"81.5"、血压"{\"systolicBloodPressureValue\":120,\"diastolicBloodPressureValue\":80}"。
- 优点:后端处理逻辑简单,资源结构完全统一;
- 缺点:客户端需要自行解析字符串为对应类型,极易出错;丢失数据类型语义,无法用JSON Schema做校验,API文档可读性差。这种方案业内很少作为首选,仅适用于极端简单场景或兼容老旧系统。
关于多态设计的混乱问题
多态设计确实会增加客户端复杂度,但通过以下手段可以有效降低混乱:
- 在API文档中明确标注每种
observationType对应的observationValue类型与结构; - 用JSON Schema定义资源结构,支持动态类型校验;
- 后端严格遵循类型对应关系,杜绝类型不匹配的返回数据;
- 为强类型客户端提供SDK,封装类型判断与转换逻辑。
内容的提问来源于stack exchange,提问作者Carlos Gonzalez
相关产品推荐
相关产品推荐

