Flutter医疗健康数据交互插件fhir_client的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter医疗健康数据交互插件fhir_client的使用

fhir_client

fhir_client简化了在Dart中与FHIR®数据进行交互的工作。 它提供了一个用户友好的API来与FHIR®服务器进行交互,并以其非破坏性的JSON处理而突出. 它使用库Jayse来在序列化和反序列化过程中保持FHIR®数据的完整性. 这个特性确保所有数据元素都被准确表示,使类型安全的操作在与FHIR®服务器工作时不会丢失数据.

基本用法

这个代码搜索实践者的日程安排. 代码不会抛出异常, 并且你可以保证它将返回你看到的两种类型的其中一个. 当有错误时, 代码将返回一个OperationOutcome.

import 'package:fhir_client/fhir_extensions.dart';
import 'package:fhir_client/models/basic_types/fixed_list.dart';
import 'package:fhir_client/models/codeable_concept.dart';
import 'package:fhir_client/models/reference.dart';
import 'package:fhir_client/models/resource.dart';
import 'package:fhir_client/models/value_sets/slot_status.dart';
import 'package:http/http.dart';

// The base HAPI API URI
const baseUri = 'http://hapi.fhir.org/';

Future<void> main() async {
  // Use any old HTTP Client and you can mock this
  final client = Client();

  final results = await Future.wait([
    client.searchSlots(
      baseUri,
      count: 10,
      status: SlotStatus.free,
    ),
    client.searchSchedules(baseUri, count: 10),
    client.searchPractitionerRoles(baseUri, count: 10),
  ]);

  final formattedResult = results
      .map(
        (result) => switch (result) {
          (final BundleEntries<Schedule> schedules) =>
            'Schedules:\n\n${schedules.formatResult(_formatSchedule)}',
          (final BundleEntries<Slot> slots) =>
            'Slots:\n\n${slots.formatResult(_formatSlot)}',
          (final BundleEntries<PractitionerRole> roles) =>
            'PractitionerRoles:\n\n'
                '${roles.formatResult(_formatPractitionerRole)}',
          (final OperationOutcome<Resource> oo) when oo.text != null =>
            'Error: ${oo.text?.status}\n'
                '${oo.text?.div}',
          _ => 'Unknown Result',
        },
      )
      .join('\n');

  print(formattedResult);
}

示例Demo

下面是一个完整的示例demo,展示了如何使用fhir_client插件来搜索实践者的日程安排并打印结果。

import 'package:fhir_client/fhir_extensions.dart';
import 'package:fhir_client/models/basic_types/fixed_list.dart';
import 'package:fhir_client/models/codeable_concept.dart';
import 'package:fhir_client/models/reference.dart';
import 'package:fhir_client/models/resource.dart';
import 'package:fhir_client/models/value_sets/slot_status.dart';
import 'package:http/http.dart';

// The base HAPI API URI
const baseUri = 'http://hapi.fhir.org/';

Future<void> main() async {
  // Use any old HTTP Client and you can mock this
  final client = Client();

  final results = await Future.wait([
    client.searchSlots(
      baseUri,
      count: 10,
      status: SlotStatus.free,
    ),
    client.searchSchedules(baseUri, count: 10),
    client.searchPractitionerRoles(baseUri, count: 10),
  ]);

  final formattedResult = results
      .map(
        (result) => switch (result {
          (final BundleEntries<Schedule> schedules) =>
            'Schedules:\n\n${schedules.formatResult(_formatSchedule)}',
          (final BundleEntries<Slot> slots) =>
            'Slots:\n\n${slots.formatResult(_formatSlot)}',
          (final BundleEntries<PractitionerRole> roles) =>
            'PractitionerRoles:\n\n'
                '${roles.formatResult(_formatPractitionerRole)}',
          (final OperationOutcome<Resource> oo) when oo.text != null =>
            'Error: ${oo.text?.status}\\n'
                '${oo.text?.div}',
          _ => 'Unknown Result',
        }),
      ).join('\n');

  print(formattedResult);
}

String _formatCodingListList(FixedList<CodeableConcept> list) =>
    list.map(_formatCodingList).join('/n');

String _formatCodingList(CodeableConcept? cc) =>
    cc?.coding
        ?.map((coding) => '${coding.code} - ${coding.display}')
        .join(', ') ??
    '';

String _formatPractitionerRole(PractitionerRole pr) => 'Id: ${pr.id}\nCodes:\n'
    '${_formatCodingListList(FixedList(pr.code ?? []))}\n';

String _formatSlot(Slot slot) => 'Id: ${slot.id}\n'
    'Appointment Type: ${_formatCodingList(slot.appointmentType)}\n'
    'Service Category: '
    '${_formatCodingListList(FixedList(slot.serviceCategory ?? []))}\\n'
    'Service Type: '
    '${_formatCodingListList(FixedList(slot.serviceType ?? []))}\\n'
    'Start ${slot.start} End: ${slot.end}\nComment: ${slot.comment}\';

String _formatActor(FixedList<Reference> actors) => 'Actors:\n${actors.map(
      (actor) => ' - '
          '${actor.reference}: ${switch (actor.display) {
        (final String displayValue) => displayValue,
        _ => 'N/A',
      }}',
    ).join('\n')}';

String _formatSchedule(Schedule schedule) =>
    'Schedule ID: ${schedule.id}\nSlot Start: '
    '${schedule.planningHorizon?.start!.toIso8601String()}\nSlot End: '
    '${schedule.planningHorizon?.end!.toIso8601String()}\\n'
    'Service Types:\n'
    '${_formatCodingListList(FixedList(schedule.serviceType ?? []))}\\n'
    'Service Categories:\n'
    '${_formatCodingListList(FixedList(schedule.serviceCategory ?? []))}\\n'
    '${_formatActor(FixedList(schedule.actor ?? []))}';

测试和模拟

该库设计用于使测试变得容易。您可以使用http包中的MockClient类来模拟客户端。以下是如何使用MockClient模拟客户端的示例:

MockClient _mockClient(String filePath) => MockClient(
  (r) => Future.value(
    Response(
      File(filePath).readAsStringSync(),
      200,
    ),
  ),
);

group('getResource API Call Tests', () {
  /// A test function that can be called with a mocked client
  /// or a real one
  Future<void> readOrganization(Client client) async {
    const path = 'baseR4/Organization/2640211';

    final result =
        await client.getResource<Organization>(baseUri, path) as Organization;

    expect(result.id, '2640211');
    expect(result.identifier!.first.type!.text, 'SNO');
  }
  // ...
});

更多关于Flutter医疗健康数据交互插件fhir_client的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter医疗健康数据交互插件fhir_client的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用fhir_client插件来进行医疗健康数据交互的示例代码。fhir_client是一个用于与FHIR(Fast Healthcare Interoperability Resources)服务器进行交互的Flutter插件。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加fhir_client依赖:

dependencies:
  flutter:
    sdk: flutter
  fhir_client: ^x.y.z  # 请替换为最新版本号

然后运行flutter pub get来安装依赖。

2. 导入包

在你的Dart文件中导入fhir_client包:

import 'package:fhir_client/fhir_client.dart';

3. 配置FHIR客户端

配置一个FHIR客户端实例,通常你需要设置服务器的URL:

FhirClient fhirClient = FhirClient(baseUrl: Uri.parse('https://your-fhir-server-url.com/fhir'));

4. 认证(如果需要)

如果你的FHIR服务器需要认证,你可能需要设置认证头。例如,使用Bearer Token认证:

final Map<String, String> headers = {
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
};
fhirClient.defaultHeaders = headers;

5. 执行FHIR操作

获取患者资源

以下是一个获取患者资源的示例:

Future<void> fetchPatient() async {
  try {
    // 假设我们有一个患者的ID
    String patientId = '12345';
    
    // 获取患者资源
    Patient patient = await fhirClient.read<Patient>('Patient/$patientId');
    
    // 输出患者姓名
    print('Patient Name: ${patient.name?.first?.family}, ${patient.name?.first?.given?.first}');
  } catch (e) {
    print('Error fetching patient: $e');
  }
}

搜索患者资源

以下是一个搜索患者资源的示例:

Future<void> searchPatients() async {
  try {
    // 搜索条件,例如按名字搜索
    SearchQuery searchQuery = SearchQuery.withParam('name', 'John Doe');
    
    // 执行搜索
    Bundle bundle = await fhirClient.search<Patient>(searchQuery);
    
    // 输出搜索结果
    bundle.entry?.forEach((entry) {
      if (entry.resource is Patient) {
        Patient patient = entry.resource as Patient;
        print('Found Patient: ${patient.name?.first?.family}, ${patient.name?.first?.given?.first}');
      }
    });
  } catch (e) {
    print('Error searching patients: $e');
  }
}

6. 完整示例

以下是一个完整的示例,将上述步骤整合在一起:

import 'package:flutter/material.dart';
import 'package:fhir_client/fhir_client.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    
    // 配置FHIR客户端
    FhirClient fhirClient = FhirClient(baseUrl: Uri.parse('https://your-fhir-server-url.com/fhir'));
    
    // 设置认证头(如果需要)
    final Map<String, String> headers = {
      'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    };
    fhirClient.defaultHeaders = headers;
    
    // 获取患者资源
    fetchPatient(fhirClient);
    
    // 搜索患者资源
    searchPatients(fhirClient);
  }

  Future<void> fetchPatient(FhirClient fhirClient) async {
    try {
      String patientId = '12345';
      Patient patient = await fhirClient.read<Patient>('Patient/$patientId');
      print('Patient Name: ${patient.name?.first?.family}, ${patient.name?.first?.given?.first}');
    } catch (e) {
      print('Error fetching patient: $e');
    }
  }

  Future<void> searchPatients(FhirClient fhirClient) async {
    try {
      SearchQuery searchQuery = SearchQuery.withParam('name', 'John Doe');
      Bundle bundle = await fhirClient.search<Patient>(searchQuery);
      bundle.entry?.forEach((entry) {
        if (entry.resource is Patient) {
          Patient patient = entry.resource as Patient;
          print('Found Patient: ${patient.name?.first?.family}, ${patient.name?.first?.given?.first}');
        }
      });
    } catch (e) {
      print('Error searching patients: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter FHIR Client Example'),
        ),
        body: Center(
          child: Text('Check console for output'),
        ),
      ),
    );
  }
}

注意:在实际应用中,你可能需要将认证逻辑(如获取和刷新访问令牌)与UI交互结合起来,并在适当的时候处理错误和状态更新。这个示例主要是为了展示如何使用fhir_client插件进行基本的FHIR操作。

回到顶部