The second time, we will exchange data with EHRbase using REST API. EHRbase has many REST APIs, including those under development. This time, I will introduce the following APIs related to Template and Composition.
To handle the REST API of EHRbase, it is easy to use the Swagger UI of the Web provided by EHRbase. However, I think it is better to use Postman for development because there is no leftover.
There are many tools for creating openEHR templates, some of which can be created on the web, but Ocean Template Designer has a long history and many users.
Interfaces were implemented in RPC and SOAP from the 1990s to the early 2000s when the development of openEHR began. As an external interface, a calling language called AQL (Archetype Query Language) is prepared, and it was common in openEHR to use it to communicate with the outside. However, in the 2010s, REST API became mainstream, and each company that implemented openEHR, including cooperation with FHIR, implemented REST API.
As openEHR, REST API is standardized and released as follows.
https://specifications.openehr.org/releases/ITS-REST/latest
However, an API using the simplified JSON format was announced by Marand, and as a result of following other implementations because it is convenient, there are variations in parameters and simplification methods. As a result of discussions at the openEHR specification development committee, the simplified data format has also been standardized and is published as follows.
Simplified data template standard https://specifications.openehr.org/releases/ITS-REST/latest/simplified_data_template.html
Marand EHR Cape API https://dev.ehrscape.com/api-explorer.html
EtherCIS, one of the predecessors of EHRbase, had its own simplifications, but it has now been removed and is being implemented based on the new simplified data template standard. (Scheduled to be released around December 2020)
I will not explain the REST API again. To simplify it tremendously, access a specific URL using the HTTP method and exchange data, but I think that EHRbase is deployed in each environment, so it is not possible to write a unified URL notation. .. Therefore, this time, omit the part from http: // to ehrbase / in the URL below and write the REST API as shown below (please let me know if there is a good way to write it).
Example: When trying to incorporate information related to ehr_id with parameters using the GET method at http: // localhost: 8080 / ehrbase / rest / openehr / v1 / ehr
GET /rest/openehr/v1/ehr/{{ehr_id}}
Parameters
key | value |
---|---|
subject_id | ins01 |
subject_namespace | ehr_craft |
The actual request issued is as follows. The {{}} that appears in the URL indicates that it is a variable part.
curl -X GET "http://localhost:8080/ehrbase/rest/openehr/v1/ehr/f2e3ebf3-596b-4067-9f76-8f4f19c0c474?subject_id=ehr_craft&subject_namespace=ins01" -H "accept: application/xml"
EHR class openEHR manages data on a patient-by-patient basis. The unit that stores data for each patient is EHR. Imagine making a box to store patient data, not the EHR system itself. Therefore, creating an EHR using the REST API does not mean creating an EHR system. In the openEHR architecture, attribute information such as patient name, address, and gender is not stored directly in EHR, but is linked by calling the EHR class ID from an external patient information database.
This is designed with the assumption that EHR will be used as an anonymous database.
If you just want to create a new EHR record, just POST with no parameters as below.
POST /rest/openehr/v1/ehr
Please replace the part of localhost: 8080 in the URL in each environment. You will receive a response as shown below, so you need to save the ehr_id.
{
"system_id": {
"_type": "HIER_OBJECT_ID",
"value": "b1718dd8-a45a-4ebf-a1d6-9a9fd7ca36fb"
},
"ehr_id": {
"_type": "HIER_OBJECT_ID",
"value": "fa95a254-feb0-4b03-9fe3-193d7d485d45"
},
"ehr_status": {
"_type": "EHR_STATUS",
"subject": {
"_type": "PARTY_SELF",
"external_ref": {
"_type": "PARTY_REF",
"namespace": "default",
"id": {
"_type": "HIER_OBJECT_ID",
"value": "a258c07e-7b64-4062-b449-f96504e54a94"
}
}
},
"uid": {
"_type": "HIER_OBJECT_ID",
"value": "1220e446-b637-4c39-a62b-1e53f479ffea"
},
"is_queryable": true,
"is_modifiable": true
},
"time_created": "2020-09-26T02:11:21.214052"
}
The EHR ID is the following part.
"ehr_id": {
"_type": "HIER_OBJECT_ID",
"value": "fa95a254-feb0-4b03-9fe3-193d7d485d45"
},
Save the EHR ID as you will need it when reading the EHR data. If you don't know, EHRbase doesn't have an API to get a list of EHR IDs, so you have to look inside PostgreSQL.
If the patient ID already exists like the medical examination ticket number, attach the following JSON message and POST to / rest / v1 / ehr to save the external ID as well.
POST /rest/openehr/v1/ehr
body
{
"_type": "EHR_STATUS",
"subject": {
"external_ref": {
"id": {
"_type": "GENERIC_ID",
"value": "ins11",
"scheme": "id_scheme"
},
"namespace": "ehr_craft",
"type": "PERSON"
}
},
"is_modifiable": "true",
"is_queryable": "true"
}
Please note that in the EHRbase sample and Swagger UI, ITEM contains blank other_details, which gives an error.
If the external ID is duplicated, the following error will be returned, so don't worry too much and issue EHR more and more.
{
"error": "Specified party has already an EHR set (partyId=ce8bf586-125d-4c28-9970-465eacbaa8c4)",
"status": "Conflict"
}
Let's call the EHR created by POST by EHR ID. In place of {{EHR ID}}, specify the ehr_id returned earlier.
GET /rest/openehr/v1/ehr/{{EHR ID}}
If it has been created, the same data as the registered contents will be returned. The default is JSON, but if you specify Accept application / xml in the HTTP Header as shown below, the data will be returned in XML format.
HTTP header
key | value |
---|---|
Accept | application/xml |
GET /rest/openehr/v1/ehr/
Parameters
key | value |
---|---|
subject_id | 0001 |
subject_namespace | NPO openEHR Japan |
In openEHR, the unit of data registered in EHR is Composition, and medical record records, various reports, inspection results, etc. are recorded as Composition. Various constraints are described in Template based on Composition.
As an example, create a template to monitor body temperature and symptoms. The Archetypes used are:
After creating a template using Ocean Template Designer, export it as an "Available Template". The file whose file identifier is output as opt is called Operational Template (hereinafter referred to as OPT). All the data to be handled is defined in this file and written in XML.
If you put a space in the Tempate ID, problems such as EHRbase not being able to read it occurred, so please avoid it at this time.
The OPT used this time is released as symptom_screening.opt.
Let's register Template (OPT) in EHRbase by POST.
POST /rest/openehr/v1/definition/template/adl1.4
Paste the contents of the opt file created earlier into the body. Template is identified by template_id and uid, so if either one is worn, an error will be returned.
<uid>
<value>17bed299-2c1e-42cc-afb3-6d78002dcce3</value>
</uid>
<template_id>
<value>symptom_screening</value>
</template_id>
Use the GET method to check if the POSTed Template is registered in EHRbase. Let's read it using the template_id of the template registered earlier. Enter symptom_screening in place of {{template_id}}.
GET /rest/openehr/v1/definition/template/adl1.4/{{template_id}}
The registered OPT will be returned as a response.
Get and check the currently registered list.
GET /rest/openehr/v1/definition/template/adl1.4/
A list like the one below will be returned
[
{
"concept": "symptom_screening",
"template_id": "symptom_screening",
"archetype_id": "openEHR-EHR-COMPOSITION.health_summary.v1",
"created_timestamp": "2020-09-25T03:17:54.134Z"
}
]
Creating an instance of JSON or XML based on the contents defined in Template is not so easy, so I am creating an automatic tool.
EHRbase provides openEHR-SDK, which can generate a group of classes that can access EHRbase from OPT.
I was developing a group of tools that automatically generate a template for the JSON instance used this time, but it took a long time to investigate because the JSON instance was not published so much in the first place. Finally, I created an instance that works one day ago, so this time I will perform Composition access based on it.
The created procedure is as follows.
The created instance is published to GIST.
https://gist.github.com/skoba/cca9f69004a229e5922a0e3e73dca53e
Register the created Composition instance using the REST API. It will be linked to the EHR ID that has already been registered.
POST /rest/openehr/v1/ehr/{{EHR ID}}/composition
Let's paste the JSON of GIST into the body.
The respose header is important. The ETag contains data in the format "89b114ea-59bd-4d98-b9b8-ad8f819a5aa3 :: local.ehrbase.org :: 1", which is called the Versioned Object UID. The UUID assigned to the Composition record and the unique URL and version number registered in the EHR are written separated by ::. This UUID will be the ID of the Composition record.
Read the data registered using the EHR ID and Composition ID.
GET /rest/openehr/v1/ehr/{{EHR ID}}/composition/{{Composition ID}}
Enter the registered EHR ID and Composition ID in {{EHR ID}} and {{Composition ID}}, respectively. The same data as the registered JSON will be returned.
Use PUT to change the content if there is a correction.
PUT /rest/openehr/v1/ehr/{{EHR ID}}/composition/{{Composition ID}}
For boody, use a modified version of JSON.
The important thing here is the Coposition VersionObjectUID that was also in the Etag earlier. Specify as follows in HTTP request header.
key | value |
---|---|
If-Match | version_object_uid |
If successful, the new version object uid will be returned in the ETag of the response header.
All COMPOSITION is versioned in openEHR. If you use the versioned object uid mentioned earlier, you can retrieve the data before and after the composition you updated earlier.
GET /rest/openehr/v1/ehr/{{EHR ID}}/composition/{versioned object uid}}
Change the version at the end to see the difference in the data.
In openEHR, deleting a record is only a logical deletion, it just becomes unreadable and continues to be saved as a database. It's a rare feature, but if you want to delete it, use DELETE with the latest versioned oject uid.
DELETE /rest/openehr/v1/ehr/{{EHR ID}}/composition/{versioned object uid}}
If you specify a version other than the latest version, that version will be deleted, but you can still read other versions. If you delete the latest version, you will not be able to access it from the API including the old version.
Recommended Posts