FHIR平台應用程式開發
====
本文假設前提是除Bundle外,相關資料皆已匯入FHIR Server。以癌要事前審查為例,Bundle必須包含Claim及相關Profile。主要開發工具是[firely .NET SDK](https://docs.fire.ly/projects/Firely-NET-SDK/en/latest/)相關技術包含:
* FHIR Client
* FHIR Search / Bundle parsing
* FHIRPath
* FHIR Read
* FHIR Model
* FHIR Serialization
我們將工作分成三個步驟:
步驟一:取得FHIR Server Claim清單
---
這個步驟的重點在透過FHIR Client連接FHIR Server,設定搜尋條件後,使用FHIR Search取得Claim的清單。還傳值以Bundle封裝,因此需解析Bundle的結構才能列相關資料。
```
FhirClient client = new FhirClient("http://localhost:8080/fhir");
// Read all Claim resource from the server with a search query
var searchParams = new SearchParams();
searchParams.Add("status", "active");
// read limit to 50 results
searchParams.LimitTo(50);
var bundle = await client.SearchAsync<Claim>(searchParams);
foreach (var entry in bundle.Entry)
{
var claim = (Claim)entry.Resource;
Console.WriteLine($"Claim ID: {claim.Id}, Status: {claim.Status}, Type: {claim.Type.Coding[0].Code}");
}
```
步驟二:取得Claim所對應之Profile(Reference)清單
---
使用FHIR Modle根據Resource id取得特定Claim Resource,同時使用FHIRPath語法,取的Claim相關Profile的Reference清單。這一段FHIRPath`descendants().where($this is Reference).reference`就是取得該Resource物件下,資料格式為Resource的Elemet,並回傳reference。
Claim所包含的Profile也有第二階的Reference,此時可應用相同技術,取的所有Bundle所需要之Reference清單。
```
// Read a specific Claim by ID
var claimId = "9f76d5a5-30c0-419a-9e32-9605a095de49"; // replace with actual Claim ID
var specificClaim = await client.ReadAsync<Claim>($"Claim/{claimId}");
Console.WriteLine($"Specific Claim ID: {specificClaim.Id}, Status: {specificClaim.Status}, Type: {specificClaim.Type.Coding[0].Code}");
// using FHIR path to get all reference to Claim
var directReferenceValues = specificClaim.Select("descendants().where($this is Reference).reference");
// Print the number of references found
Console.WriteLine($"Number of direct references in Claim {specificClaim.Id}: {directReferenceValues.Count()}");
foreach (var refValue in directReferenceValues)
{
Console.WriteLine($"Direct Reference: {refValue}");
}
```
步驟三:產生Bundle
---
首先,新增一個Bundle物件,並根據前一步驟所得的Reference清單,將Claim以及相關Profile,從FHIR Server讀取後加入Bundle.Entry。
產生Bundle後,可使用FHIR Serialization技術,將FHIR Bundle物件轉換為Json格式。
```
// Create a Bundle to hold the Claim resources
var claimBundle = new Bundle
{
Type = Bundle.BundleType.Collection,
Timestamp = DateTimeOffset.Now,
Id = Guid.NewGuid().ToString(), // Generate a new unique ID for the bundle
Meta = new Meta
{
Profile = new List<string> { "https://nhicore.nhi.gov.tw/pas/StructureDefinition/Bundle-twpas" }
},
Entry = new List<Bundle.EntryComponent>()
};
// add specificClaim to the Bundle
claimBundle.Entry.Add(new Bundle.EntryComponent
{
Resource = specificClaim,
FullUrl = $"urn:uuid:{specificClaim.Id}"
});
// add directReferenceValues to the Bundle as Reference resources
foreach (var reference in directReferenceValues)
{
if (reference is Hl7.Fhir.Model.FhirString refString)
{
Bundle.EntryComponent entry = new Bundle.EntryComponent
{
Resource = await client.ReadAsync<Resource>(refString.Value), // Read the resource from the FHIR server
FullUrl = $"urn:uuid:{refString.Value}" // Set the full URL to the reference ID
};
claimBundle.Entry.Add(entry); // Add the entry to the bundle
}
}
// Serialize the Bundle to JSON with pretty print
var fhirJsonSerializer = new FhirJsonSerializer(new SerializerSettings { Pretty = true });
var bundleJson = fhirJsonSerializer.SerializeToString(claimBundle);
// print the serialized JSON
Console.WriteLine(bundleJson);
```