GSoC 2021: Support for Extended Operations in FHIR Final Evaluation
Project Summary
Title - Support for Extended Operations in FHIR
Primary Mentor: @varung31
Backup Mentor: @ibacher
Student: @medhavi
Overview
The main objective of this project was to add support for some extended operations in the FHIR2 module of OpenMRS. FHIR2 already had extensive support for searching, but with this project, the goal was to create operations that already had logic built so as to reduce the searching overhead of OpenMRS clients.
Project Objectives
This project aimed at adding support for
-
$lastn
operation on Observation -
$lastn-encounters
operation on Observation - Instance-level
$everything
operation on Patient - Type-level
$everything
operation on Patient
Operations Overview
$lastn
The $lastn
operation is used to fetch the most recent n
Observations for a specified patient(s) or all.
However, n
here is not a limitation on the number of resources that should be in the response. Rather, it is a limitation on the count of distinct effective datetimes of the Observation. It is similar to dense ranking in SQL. So if more than one Observations have the same effective datetime, both should be in the response.
It takes the following parameters:
- max
- subject or patient
- category
- code
If max
is not given, it is considered as 1. If no patient or subject param is in the request, the operation performed on all patients.
The resources in the response of the $lastn
are grouped code-wise, and within each group, the resources are sorted in non-increasing order of Observation effective datetimes and the count of distinct effective datetimes is up to n
.
$lastn-encounters
The $lastn-encounters
is similar to the $lastn
operation. But here instead of sorting the Observations, we sort the Encounters in non-increasing order of effective datetimes. Then the most recent n
Encounters are retrieved. Finally we get the Observations corresponding to these Encounters. On these Observations, the filtering is done according to any other parameters given like code
or category
. Same as $lastn
, n
is the limitation on the count of distinct Encounter effective datetimes.
It takes the same parameters as $lastn
.
$everything on Patient
The $everything
operation if used to fetch all the information at once about a specific patient(instance level) or for each patient(type level) if no id
is specified in the request. For example, a patient can have multiple Observations, Encounters, Diagnostic Reports etc, which are not present in the Patient table but refer to the patient. So we need to include these resources as well as the Patient resource itself.
The functionality which we used was _revinclude
. Just like in search, we add a HashSet for the _reviclude resources and manually add all the relevant resources viz. Observation
, Encounter
, AllgeryIntolerance
, MedicationRequest
, DiagnosticReport
, PrcodureRequest
, ServiceRequest
.
HashSet<Include> revIncludes = new HashSet<>();
revIncludes.add(new Include(FhirConstants.OBSERVATION + ":" + FhirConstants.INCLUDE_PATIENT_PARAM));
It takes the parameter:
- id (patient id for instance-level)
- _count
If _count is not mentioned, no pagination should be done.
So to prevent pagination. we used wrapped up the response in a SimpleBundleProvider
and set its page size as the count of resources. SearchQueryBundleProvider treated the _revinclude and _include resources as extras. Using SimpleBundleProvider
, the count of the _revinclude
resources is also taken into account while calculating the total
.
Contributions
- FM2-393: Support for $lastn on Observations in R4
- FM2-394: Support for $lastn on Observations in R3
- FM2-398: Integration Tests for $lastn on Observations
- FM2-404: Improve unit tests for $lastn on Observations
- FM2-400: Support for $lastn-encounters on Observations in R4
- FM2-401: Support for $lastn-encounters on Observations in R3
- FM2-402: Integration Tests for $lastn-encounters on Observations
Instance-level $everything operations on Patient
- FM2-411: Support for instance-level $everything on Patient in R4
- FM2-412: Support for instance-level $everything on Patient in R3
- FM2-416: Integration Tests for instance-level $everything on Patient
Type-level $everything operations on Patient
- FM2-418: Support for type-level $everything on Patient in R4
- FM2-419: Support for type-level $everything on Patient in R3
- FM2-420: Integration Tests for type-level $everything on Patient
Weekly Updates
Video Presentation
Future Works
We have achieved all of our primary goals. Our secondary goals were to implement the type-level and instance-level $everything
operation on Encounters, which is yet to be complete. To improve the functionality of $lastn
and $lastn-encounters
we can look into adding some kind of support for specifying patients by more than just patient id, like we see in search
that a patient can be specified using name
, family name
, given name
etc. This was actually done using chainWhitelist
in search
, since it is a function of OptionalParam
. We couldn’t do this because methods annotated with Operation
do not support OptionalParam
and OperationParam
did not have chainWhitelist
support.
Thoughts on GSoC
GSoC has been a great learning experience. It was my first major Open Source experience. These ten weeks have given me valuable experience and knowledge. I gained practical experience with Spring, Hibernate and Mockito during these ten weeks. I feel like I have grown as a software engineer. I learnt about how to write clean, readable, maintainable code, code-reusability and many such concepts which I had not been implementing to a decent extent in my projects. Every PR review felt like a point to imbibe.
I remember struggling to create a decent proposal for GSoC, because many of the things were out of my comprehension. I understood what we wanted to do, but was lacking on the how to do it part. I was afraid that I would fail miserably with the project because I couldn’t even fully understand the search
workflow. But my mentors @varung31 and @ibacher helped me throughout. I was hesitant in asking for help, since I felt I would be perceived as incapable, but through these 10 weeks, I have progressed in overcoming that hesitation and learnt that you can only grow and move ahead when you reach out for help. Hoping to continue improving my communication skills. I am extremely grateful for my mentors, for the time, efforts they invested and the guidance that they have been providing me since the beginning of my journey with OpenMRS.
I am very grateful to the OpenMRS community. It was a pleasure to work with such a wonderful, supporting community. I got to connect with some wonderful people through OpenMRS. Grateful for this experience. Thank you OpenMRS!
#gsoc21 #gsoc-finaleval