GSoC 2021: Support for Extended Operations in FHIR - Final Presentation

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


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


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 .


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.




Instance-level $everything operations on Patient

Type-level $everything operations 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