Dart/Flutter 中用于 FHIR 资源的 Json oneOf

Posted

技术标签:

【中文标题】Dart/Flutter 中用于 FHIR 资源的 Json oneOf【英文标题】:Json oneOf in Dart/Flutter for FHIR resources 【发布时间】:2020-05-18 17:22:29 【问题描述】:

我正在尝试为 Json 中定义的 FHIR 资源创建 Dart 类。如果有人想看,完整的Json schema for FHIR is here。我的问题是 oneOf 声明。具体来说,我有一个类似以下的类(我没有在这里包含完整的类定义,尽管如果有人认为它会有所帮助,我可以):

class Bundle_Entry 
  Resource resource;

Bundle_Entry(this.resource);

  factory Bundle_Entry.fromJson(Map<String, dynamic> json) => _$Bundle_EntryFromJson(json);
  Map<String, dynamic> toJson() => _$Bundle_EntryToJson(this);
 

我的问题是 ResourceList 被定义为许多其他类中的一个。

"ResourceList": 
  "oneOf": [
     "$ref": "#/definitions/Account" ,
     "$ref": "#/definitions/ActivityDefinition" ,
    ...
  ]

我尝试将“resource”变量声明为“var”、“dynamic”和“ResourceList”类型,并创建了一个仅包含资源的类 ResourceList。

每个资源都有一个名为“resourceType”的字段,所以我也尝试创建一个 ResourceList 函数,该函数根据“resourceType”的参数返回不同的类型,这也不起作用。

如果我执行 http 请求,我尝试解析的实际响应如下所示:


  "resourceType": "Bundle",
  "type": "searchset",
  "entry": [
      
          "resource": 
              "name": "Jaba the Hutt"
              "birthDate": "1980-07-27",
              "id": "b26646dd-c549-4981-834e-bb4145d104b8",
              "resourceType": "Patient"
           
      
    ]

任何建议将不胜感激。

更新我的问题。有趣的是,第一个答案与我目前想出的相似。

class Bundle_Entry 
  dynamic resource;
  Bundle_Entry(this.resource);

  Bundle_Entry.fromJson(Map<String, dynamic> json) =>
      Bundle_Entry(
        resource: json['resource'] == null
        ? null
        : ResourceTypes(
            json['resource']['resourceType'], json['resource'] as Map<String, dynamic>)
);

  Map<String, dynamic> toJson() => _$Bundle_EntryToJson(this);


dynamic ResourceTypes(String type, Map<String, dynamic> json) 
  if (type == 'Element') return (new Element.fromJson(json));
  if (type == 'Extension') return (new Extension.fromJson(json));
  if (type == 'Patient') return (new Narrative.fromJson(json));

我的问题是我必须对每个 ResourceType 进行硬编码,而且似乎应该有更简单的方法。

【问题讨论】:

【参考方案1】:

我一直在尝试构建类似的东西。我使用继承来处理它,并创建了一个函数来根据 ResourceType 字段返回资源。

Resource getResource(json) 
  if(json == null) return null;
  if(json["resourceType"] == "Patient") return Patient.fromJson(json);
  if(json["resourceType"]=="Procedure") return Procedure.fromJson(json);
  if(json["resourceType"]=="Encounter") return Encounter.fromJson(json);
  if(json["resourceType"]=="Appointment") return Appointment.fromJson(json);
  if(json["resourceType"]=="Slot") return Slot.fromJson(json);
  if(json["resourceType"]=="Slot") return Slot.fromJson(json);
  if(json["resourceType"]=="Observation") return Observation.fromJson(json);
  if(json["resourceType"]=="Condition") return Condition.fromJson(json);
  if(json["resourceType"]=="DiagnosticReport") return DiagnosticReport.fromJson(json);
  if(json["resourceType"]=="MedicationRequest") return MedicationRequest.fromJson(json);
  if(json["resourceType"]=="CarePlan") return CarePlan.fromJson(json);
  if(json["resourceType"]=="Practitioner") return Practitioner.fromJson(json);
  if(json["resourceType"]=="AllergyIntolerance") return AllergyIntolerance.fromJson(json);

  return Resource.fromJson(json);

其中 Patient、Procedure 等是 Resource 的子类:

class Entry 
  String fullUrl;
  Resource resource;

  factory Entry.fromJson(Map<String, dynamic> json) => Entry(
        fullUrl: json["fullUrl"] == null ? null : json["fullUrl"],

        //This line is the magic
        resource: getResource(json["resource"]),
        search: json["search"] == null ? null : Search.fromJson(json["search"]),
        response: json["response"] == null
            ? null
            : Response.fromJson(json["response"]),
      );

【讨论】:

既然您建议将此作为答案,请提供完整代码。答案需要为问题提供可行的答案 我更新了帖子。如果您希望我添加更多内容,请告诉我。

以上是关于Dart/Flutter 中用于 FHIR 资源的 Json oneOf的主要内容,如果未能解决你的问题,请参考以下文章

参考资源中的 FHIR 搜索

自动完成/智能感知不适用于 VSCode 中的 dart/flutter

Dart/Flutter:快速检查 404 链接列表

FHIR 药物管理 - 当前剂量

VSCode:Prettier 不适用于 Dart Flutter

使用 FHIR nuget 包通过引用查找包中的资源