HAPI FHIR介紹
===
本文主要根據James Agnew - Introduction to HAPI | DevDays 2023 Amsterdam的演講內容並參考HAPI官網內容做快速整理。
https://www.youtube.com/watch?v=d6aAXi38Kow&list=PLKuZNI94tzWY1J988TdEGhJ69r4DnTiAN&index=111&t=1560s
Working with Resource
---
每一個Resource都有對應的Class,透過各自的getter/setter function來設定與讀取該Resource所對應的properties。
```
Observation obs = new Observation();
// 以下三種寫法,其結果相同
obs.setIssuedElement(new InstantType(new Date()));
obs.setIssuedElement(new InstantType(new Date(), TemporalPrecisionEnum.MILLI));
obs.setIssued(new Date());
```
Childe Clasee: 多數的getter function會自動產生child class,
```
Observation observation = new Observation();
// None of these calls will not return null, but instead create their respective child elements.
List<Identifier> identifierList = observation.getIdentifier();
CodeableConcept code = observation.getCode();
StringType textElement = observation.getCode().getTextElement();
```
代碼處理
```
Patient patient = new Patient();
//直接寫入(若代碼值為已知)
patient.getGenderElement().setValueAsString("male");
//使用Java Enumerated types
patient.setGender(Enumerations.AdministrativeGender.MALE);
//直接讀取 String
String genderString = Patient.getGenderElement().getValueAsString();
//讀取Java Enumerated types
Enumerations.AdministrativeGender genderEnum = patient.getGenderElement().getValue();
```
Chain
```
Patient pat = new Patient()
// 建立"name" Element
HumanName name = pat.addName();
name.setFamily("Simpson").addGiven("Homer").addGiven("J");
//直接使用Chained
pat.addIdentifier().setSystem("http://acme.org/MRNs").setValue("12345");
```
Working with Data Type
---
FHIR定義了所有的基本資料型態,不使用Java既定的data type。主要原因是因為FHIR允許Extension,使用Java既定的data type會受到限制。
```
BooleanType active = new BooleanType();
active.setValue(true);
active.setValueAS("true");
```
The HAPI FHIR Context
---
FhirContect Class是所有FHIR API的進入點,由於相當耗資源,因此必須為唯一(Singleton ?)。
Using the Parser
---
```
// Create a FHIR context
FhirContext ctx = FhirContext.forR4();
// The following example is a simple serialized Patient resource to parse
String input = "{" + "\"resourceType\" : \"Patient\","
+ " \"name\" : [{"
+ " \"family\": \"Simpson\""
+ " }]"
+ "}";
// Instantiate a new parser
IParser parser = ctx.newJsonParser();
// Parse it
Patient pat = parser.parseResource(Patient.class, input);
String encode = parser.encodeResourceToSting(pat);
```
Using the HAPI FHIR Client
---
Client可以從FhirContext產生,可以執行CRUD等相關資料操作。
```
// We're connecting to a DSTU1 compliant server in this example
FhirContext ctx = FhirContext.forR4();
String serverBase = "http://fhirtest.uhn.ca/baseR4";
IGenericClient client = ctx.newRestfulGenericClient(serverBase);
// Perform a search
Bundle results = client.search()
.forResource(Patient.class)
.where(Patient.FAMILY.matches().value("duck"))
.returnBundle(Bundle.class)
.execute();
System.out.println("Found " + results.getEntry().size() + " patients named 'duck'");
```
Exception Handling
---
BaseServerResponseException Package提供完整清單
https://hapifhir.io/hapi-fhir/apidocs/hapi-fhir-base/ca/uhn/fhir/rest/server/exceptions/BaseServerResponseException.html
HAPI FHIR Server
---
共計三種:Plain Server(Facase Layer,可與醫院既有資料庫結合)、JPA Server、JAX-RS(不討論)
- JPA Server
相關資料可參考 https://github.com/hapifhir/hapi-fhir-jpaserver-starter
相關的設定、Docker Compose、application.yml等都可以找到相關參考資料。
- JPA Server Features
主要功能包含:Subsciptions、Bulk Import/Export、Partitioning、MDM、IPS、Terminology Services等。
Interceptors
---
在HTTP Request/Response的過程中,透過Hook將處理邏輯內嵌進去,在Client收到回傳資料之前,對input/output做再處理。目前HAPI FHIR Built-in的Interceptors包括:
- LoggingInterceptor
- CorsInterceptor
- RequestValidatingInterceptor
- ResponseValidatingInterceptor
- ResponseHighlighterInterceptor
- OpenApiInterceptor
Security
---
1. Authentication(在HAPI FHIR並未實作,必須與其他平台整合)
2. Authorization:使用AuthorizationInterceptor和ConsentInterceptor
3. Consent:使用ConsentInterceptor,結合FHIR Resource(Consent/Questionnaire/QuestionnaireResponse),可以整合客製化的Interceptor
4. Audit:使用BalpAuditCaptureInterceptor
Validation
---
包含兩種Validation:
* Parser Error Handler:針對JSON檔案結構檢查。
* Validator:Semantic validation,可以跟IG結合,確認資料是否符合IG的規則。