医院数据的API接口应如何管理?
距离上次和大家分享医院“中台”和“小前台”已经有一段时间了,最近一方面比较忙,一方面还是自己惰性的缘故,迟迟没有下笔。总算忙完了这一段时间,也就没有任何懒下去的理由了。
言归正传,在前两篇分享的文章中,我都提到了一个很重要的概念“API”,医院将数据资产通过API的形式开放出来构成了“数据中台”的基础,将业务逻辑通过API的形式开放出来构成了“业务中台”,而各种应用开发商通过调用API来获取或操作数据或业务。通过这种方式,应用开发商可以关注自身的业务,而不需要太多的考虑数据或业务如何集成,而医院方可以快速引入一个新的需求或替换一个应用,并将实施成本降到最低。
API作为医院开放数字资产的核心能力,它直接体现了医院的数据资产以及对这些数据资产操作的能力,比如对患者的操作可能包含创建、更新、删除、查询、合并等。同时,由于各种原因(比如安全),医院可能会选择开放哪些操作给第三方,哪些保持私有,比如开放增、改、查,但不允许删除和合并患者操作。这里面体现了API应该具备的三个必要因素:数据模型、方法、API管理。
数据模型
“数据中台”的核心能力是把医院的数据通过API的方式开放给第三方,那么医院到底有哪些数据?第三方应该如何理解这些数据呢?一个比较有效的方式是定义一个能涵盖医院业务范围的数据模型。
数据模型是对医院数据和业务的抽象表达,一个良好的数据模型是医院和厂商、厂商与厂商之间沟通的桥梁,保证不同的参与方对于医院的数据和业务理解的一致性。数据模型可以从概念模型、逻辑模型和物理模型三个不同的层面进行描述。
概念模型是最高层面的数据和业务抽象,它描述了业务领域相关概念实体的抽象。比如患者、就诊、医嘱、医嘱执行、结果、用药、诊断等,以及这些概念之间的关系。概念模型不涉及到任何实现技术的选择,因此是技术人员和业务人员沟通的重要媒介。
逻辑模型是在概念模型的基础上,充分考虑选择技术方向的特点而进一步具体化的数据模型。同样的概念模型可能随着技术选择的不同导致逻辑模型不同,比如关系模型对应了关系型数据库、文档模型对应了文档数据库、键值模型对应了键值对数据库、对象模型对应了对象型数据库等。
物理模型是对逻辑模型的具体实现,具体的数据库的设计最终和逻辑模型也会有一定的差异。比如,为了考虑数据操作的性能,可能会把某些关系表中的部分数据进行展开或冗余。以患者ID为例,下图是患者和患者ID之间的逻辑模型,PatientID实体是用来保存ID和ID的类型,比如身份证。
以上模型表明一个患者有多个患者ID,身份证只是其中的一个。而在设计数据库表时,一种可能性是把患者身份证号单独拿出来放到患者表中,这样在查询患者身份证号时,不需要查询关联表PatientID以提高查询性能。此时,物理模型就会变成下面的模型:
在这个物理模型中,身份证号成为了Patient表的一个属性,而其他的ID还保存在PatientID中。而不管选择什么样的技术或设计,最基本的原则是物理模型不能破坏逻辑模型的关系。同样,逻辑模型也不能破坏概念模型的定义。这样层层的约束可以保证不同参与方对数据理解的一致性。
目前,医院信息平台或业务系统建设面临的一大挑战是缺乏统一的概念和逻辑模型设计。很多数据中心或业务系统给医院呈现出来的只有数据库表格设计(物理模型),这就容易导致当出现一个新的需求时,为了满足该需求的快速实现,随意在数据表中增加一个或多个字段,结果导致了超级大表的出现。也最终导致没有一个人能够完整理解现有系统或数据库表的设计。而一个良好的数据模型的设计可以有效解决这一问题。
方法
方法是对前面定义的数据的操作,方法可能包含对每一个概念实体CRUD细粒度的操作,比如新增患者、更新患者、删除患者、查询患者等,也可以是非常复杂的业务操作,比如患者合并或拆分等。不管是简单还是复杂的方法,一个方法都会包含4个基本的内容:方法名、输入参数、输出、异常处理。
“方法名”体现了业务操作,反应了真实世界的业务行为,一个好的方法名可以有效地帮助第三方应用理解一个API,比如“createPatient”很容易让人理解成是一个创建新患者的API。当然,由于API实现技术的不同,很多情况下,一个操作的名字并没有这么直观,比如RESTful API是基于http的,其操作是基于http的verb,比如POST,PUT,DELETE等。如何区别一个API的直观含义是通过http verb加上对于的资源决定的?比如 POST xxx.xxx.xxx/rest/Patient 代表的是创建一个新的患者,当面对这样的API定义时,我们需要明确说明每一个http verb代表的具体年业务含义。
“输入参数”是告诉“方法”处理怎样的数据。同样,输入参数也要受概念模型的约束,比如“createPatient”的输入参数是Patient,输入参数既可以是单一实体,也可以是复杂的复合数据实体。比如,批量创建患者的输入参数是患者集合,这种选择依赖具体业务的需求。
“输出”是“方法”对对应的“输入参数”处理后的返回。同样,返回既可以是一个对象实体或复合实体,也可以是一个状态,还可以是一个异常。
“异常处理”反应了一个系统对于异常的处理能力,异常分为业务异常和系统异常。业务异常体现了一个医院的业务流程中异常部分的处理,比如更新一个不存在的患者信息,此类型的异常需要以业务能够理解的形式返回给API消费方。所有其他非业务相关的异常统称为系统异常,包括内存溢出、内存不够、超时等。为了保证系统的健壮性,此类型的异常同样需要进行管理,否则就会出现系统崩溃现象。
API管理
“中台”不仅仅是开放API给第三方调用,更重要的是能够全面管理API。由于业务变化的本质,“中台”所提供的服务并不是一成不变的。比如,增加新服务、更新原有服务、关闭已有服务等。而所有的变化都最终会体现在API的变化上,比如,医院引入胸痛中心业务,此时医院可能创建新的导管室预约API,也可能关闭某些业务,有些门诊药房业务规格可能会发生改变。再比如,为了研究家族史的影响,在患者信息中会加上家族关系信息等。而所有的改变都会最终体现在API上,因此每一个API都应包含如下生命周期管理。
在设计阶段,技术和业务人员共同定义新的API形态,包括方法名、输入、输出、异常处理、以及涉及的数据模型定义,并用标准的API描述语言进行定义(比如Open API)。通过标准的API描述语言,可以允许服务端开发人员通过代码生成工具快速生成API框架代码,从而将工作的重点放在业务逻辑的实现上,而非API本身的实现。
同样,API消费端也可以通过代码生成工具生成API调用框架代码,把所有的精力放在调用API后的业务逻辑上。通过标准的API描述语言,可以帮助进行快速开发,同时也可以快速生成相关的API说明文档,这样“中台”的消费方就可以非常方便地找到所需要的API,并了解API相关的使用说明。
一旦开发完成,还需要对API进行测试,包括自动化测试、手工测试、性能测试、回归测试等,以保证新的API的完整性和健壮性。同样,新的API也需要很容易地进行部署和发布。一个API一旦正式上线,我们就需要对每一个API进行运营管控,而API的运营管控至少包含以下四个部分:
医院根据实际安全考虑,可能只针对部分认证或授权的应用开放相关的API,甚至只对部分相关的用户开放某些患者的信息或临床信息,比如心理疾病、HIV等信息。因此,当一个API部署之后,需要对该部分的API调用策略进行设置,确保API只被认证和授权的应用或用户调用。
除了对单个API进行授权管理以外,我们还可以在整个系统层面对所有的API设定访问策略。比如,通过设定白名单或黑名单来控制哪些应用可以调用API,也可以设定对所有的API进行SSL加密。一旦API发布以后,医院也可以根据不同的应用场景来限定API调用流量、速度、大小的控制,比如针对不同的门诊预约API,可以确定微信端调用占30%、第三方移动APP占30%、官方APP占40%等。
最后,为了全面管控医院自身的数字资产,医院还需要全面的监控API的调用情况,通过监控,医院可以很容易的知道哪些应用调用了哪些API,每一个API调用的总体情况等,其中包括(不限定)非法调用告警、调用次数分析、高峰分析、API经济分析等。同时,要通过运用分析,及时发现API的价值。如果一个API从发布开始,经过一段时间运行后,只有零星调用,说明该API的价值非常低。那么可以关闭这些低价值的API,从而减少对整个资源的占用。
API并不是一成不变的,它会随着业务的变化而变化,这些变化包括API更新、API抛弃、API删除等。为了保证每一次更新不影响已经使用的应用,API需要进行版本管理,已经存在的应用继续使用久的版本。而针对新的应用则调用新版本的API,当所有旧的应用全都迁移到新的版本后,就可以将旧版本抛弃。但抛弃并不等于删除,只有当一个API从发布开始都没有调用的情况下,才可以考虑将该API删除。
【小结】
API作为“数据中台”和“业务中台”的关键技术,反映了医院数据和业务的抽象,一个良好的API应该包含完整的数据模型和方法的定义。同时,API也不是一成不变的,它反映了业务的实际变化,这些变化最终会体现在API的不同生命周期阶段。最后,为了保证API的安全和有效性,需要对API进行全面的管控,包括认证授权、安全、流量控制及运营监控。
API是医院数据资产开放的有效方式,但在现有的医院信息化架构体系下,如何构建API的能力?笔者将在后面的文章中继续和大家分享。