GSoC 2023 - Add Support for FHIR PATCH operations - Final Presentation

Add Support for FHIR PATCH operations

Overview

OpenMRS is using the FHIR API more and more in place of the REST API. However, the FHIR API is, by default, quite verbose. Supporting PATCH operations would allow us to support partial updates to FHIR resources without needing to send the whole resource from the client to the server.

The journey of enhancing OpenMRS through the addition of support for FHIR Patch Operations has been a remarkable experience. In light of the growing importance of the FHIR API as a replacement for the REST API, this project sought to introduce PATCH operations to enable more efficient partial updates to FHIR resources. This feature empowers users to modify specific elements within resources without the need to transmit entire resources between the client and the server.

In the context of the HAPI FHIR library, “patching” refers to the process of making partial updates to a FHIR (Fast Healthcare Interoperability Resources) resource. FHIR resources are representations of healthcare-related data, such as patient, observations, medications, etc., designed to be easily shared and exchanged between different healthcare systems.

Patching allows you to modify specific parts of a FHIR resource without having to replace the entire resource. This can be particularly useful when you want to make minor updates or corrections to a resource without sending the entire payload over the network. The PATCH operation follows the HTTP PATCH method semantics and is designed to be more efficient than the PUT or POST methods for updating resources, especially when dealing with large resources or slow network connections.

  • The Patch operations used within the above mentioned patch formats are add, replace, move, copy, test, remove .

Format for supporting a single patch

  1. Detect the incoming format(either json-merge patch, json-patch or xml-patch)
  2. Load the existing resource in the appropriate format
  3. Apply the patch

Objectives:

  • Implement JSON PATCH operations on all OpenMRS FHIR R4 resources and ensure to have the tests working perfectly. - COMPLETED :white_check_mark:
  • Implement JSON MERGE PATCH operations on all OpenMRS FHIR R4 resources and ensure to have the tests working perfectly. - COMPLETED :white_check_mark:
  • Implement XML PATCH operations on all OpenMRS FHIR R4 resources and ensure to have the tests working perfectly. - COMPLETED :white_check_mark:

Contributions:

During the project, I worked on various code repositories and pull requests to bring the functionality of PATCH operations to the FHIR API:

Repositories:

Pull Requests:

  1. FM2-582: Add Support for Patching on Immunization Resource by mherman22 · Pull Request #513 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:
  2. FM2-603: Add Support for UPDATE on the Observation Resource by mherman22 · Pull Request #509 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:
  3. FM2-592: Add support for XML PATCH operation - Location Resource by mherman22 · Pull Request #507 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:
  4. FM2-602: Add support for XML PATCHing operations - Encounter Resource by mherman22 · Pull Request #506 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:
  5. FM2-597: Add support for XML PATCHing operations-MedicationDispense Resource by mherman22 · Pull Request #503 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:
  6. FM2-598: Add support for XML PATCHing operations-Task Resource by mherman22 · Pull Request #502 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:
  7. FM2-599: Add support for XML PATCHing operations - Medication Resource by mherman22 · Pull Request #501 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:
  8. FM2-600: Add support for XML PATCHing operations - DiagnosticReport Resource by mherman22 · Pull Request #500 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:
  9. Add support for XML PATCHing operations - MedicationRequest Resource by mherman22 · Pull Request #499 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:
  10. FM2-593: Add support for XML patching operations - Condition Resource by mherman22 · Pull Request #498 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:
  11. FM2-594: Add support for XML patching operations - Person Resource by mherman22 · Pull Request #497 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:
  12. FM2-595: Add support for XML patching operations - AllergyIntolerance Resource by mherman22 · Pull Request #496 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:
  13. FM2-596: Add support for XML patching operations - Practitioner Resource by mherman22 · Pull Request #495 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:
  14. FM2-588: Add support for XML Patch operations - Patient Resource by mherman22 · Pull Request #493 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:
  15. FM2-587: Add Support for JSON patching operations — MedicationDispense Resource by mherman22 · Pull Request #492 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:
  16. FM2-583: Add support for Json Merge Patch operations - Practitioner Resource by mherman22 · Pull Request #491 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:
  17. FM2-586: Add support for Json Patching operations - DiagnosticReport Resource by mherman22 · Pull Request #490 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:
  18. FM2-589: Add support for Json patching operations - Encounter Resource by mherman22 · Pull Request #489 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:
  19. FM2-590: Add support for Json Merge Patch operations - Medication Resource by mherman22 · Pull Request #488 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:
  20. Add support for Json Merge Patch operations - Patient Resource by mherman22 · Pull Request #487 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:
  21. FM2-570: toOpenmrsType translators should set uuid to id part of id, not full id by mherman22 · Pull Request #485 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:
  22. FM2-585: Add support for Json Merge Patch operations - Task Resource by mherman22 · Pull Request #484 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:
  23. Fm2-579-impl: Add support for Json Patch operations - Patient Resource by mherman22 · Pull Request #483 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:
  24. FM2-580: Add support for Json Merge Patch operations - Allergy Intolerance Resource by mherman22 · Pull Request #481 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:
  25. FM2-577: Add support for Json patching operations - Person Resource by mherman22 · Pull Request #480 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:
  26. FM2-576: Add support for Json patching operations - Condition Resource by mherman22 · Pull Request #479 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:
  27. FM2-575: Add support for Json patching operations - Location Resource by mherman22 · Pull Request #478 · openmrs/openmrs-module-fhir2 · GitHub - Merged :white_check_mark:

Found Issues:

  • Medication Dispense was not added to the landing page of the FhirIG
  • Medication was not added to the landing page of the FhirIG

Fixed Issues:

Other related work:

During this GSoC jouney, i was able to do other work on the FHIR module as assigned by my mentor and below are the pull requests;-

Talk Thread links:

Jira Epic

Weekly Blog Posts:

Throughout the development cycle, I chronicled my progress and insights through weekly blog posts:

Video(Demo)

Resources:

Future Works:

While significant strides have been made, certain aspects require further attention. Completing the integration of PATCH operations with complex FHIR resources(ServiceRequest) is a priority. Additionally, refining error handling and optimizing performance will ensure a robust implementation.

Part of the work to be worked on includes but not limited to the following;-

  • Ensure Service Request resource is fully translated
  • Ensure Service Request resource supports all the PATCHing formats implemented above.
  • Write more tests in regard to the how the json documents and xml documents should be written in the attempt to give clearer error messages.(To Be Discussed)
  • We could also implement the PATCH operations for the R3 resources(To Be Discussed).

Thoughts on GSoC:

Participating in GSoC 2023 on the OpenMRS platform has been an enlightening journey. Working with esteemed mentors like Ian Bacher and Abert Namanya has been instrumental in my growth. I have gained insights into the world of healthcare informatics, API optimization, and collaborative open-source development. Looking forward, GSoC has paved the way for a continued commitment to enhancing healthcare technology. My knowledge in FHIR standards and OpenMRS data model and how the two integrate to complement each other has greatly grown.

A special thanks to GSoC, OpenMRS, mentors, and the vibrant community for making this journey a resounding success! :star2::globe_with_meridians:

cc: @kdaud @jayasanka @grace @jennifer @janflowers @erica @ibacher @dkayiwa @mozzy @samuel34 @jnsereko @jwnasambu @abertnamanya @pmanko @reagan

8 Likes

:clap: Godspeed on the journey forward writing code to save lives :clap:

Thanks so much @mherman22 for this very well written post. The demo video was especially helpful for me to visualize :slight_smile:

FYI @mseaton and @mogoodrich I imagine this PATCH operation flow might be rather useful for the Retrospective Data Entry/Editing work you have on the roadmap :slight_smile:

One small question out of curiosity from the demo - when the birthdate is changed from “1996”, you entered 2023, but it turns into “2023-01”. How does OMRS decide (or rather where is that configured) to default to January if the month is not known?

1 Like

This is handled at https://github.com/openmrs/openmrs-module-fhir2/blob/6dc997ced929e319d08857df81edd3c465ae5a07/api/src/main/java/org/openmrs/module/fhir2/api/translators/impl/BirthDateTranslatorImpl.java#L43-L49

here’s the code:

			// 5 years is the cut-off for WHO and CDC infant growth charts, so it seems like a convenient break between
			// "infant" and "child"
			if (Period.between(birthDate, now).getYears() > 5) {
				dateType.setValue(person.getBirthdate(), TemporalPrecisionEnum.YEAR);
			} else {
				dateType.setValue(person.getBirthdate(), TemporalPrecisionEnum.MONTH);
			}

To shed more light,

  • If the calculated age is greater than 5 years, the DateType is set with the precision YEAR. This means that only the year component of the birthdate will be used, and the rest of the components (month, day, time) will be ignored. i.e 1996

  • If the calculated age is 5 years or less, the DateType is set with the precision MONTH. This means that both the year and month components of the birthdate will be used, and the day and time components will be ignored. i.e 2023-01

  • Since the precision is set to MONTH, the day component defaults to the first day of the month (January 1st), and the month component remains the same (January). Therefore, when you provide a birthdate of 2023(like i did in the video), the result is 2023-01, indicating the year and month of the birthdate while disregarding the specific day and time.

  • If you were to provide a birthdate of, say, January 15, 2023, the result would still be 2023-01, as the precision is set to MONTH, and the code-snippet above doesn’t consider the day component beyond the month of January.

Note: This precision distinction aligns with the levels of precision defined in the TemporalPrecisionEnum enum class. The YEAR precision corresponds to years, and the MONTH precision corresponds to months.

probably @ibacher could correct me i’m wrong

2 Likes

great work @mherman22 :muscle:

2 Likes

This is exactly right. This is configurable in the sense that an implementation is free to override that translator with any translator that implements the same interface but returns a different date. (The FHIR2 module is basically designed so that almost all implementation details can be swapped out by other modules).

The default rule is based on the fact that international guidelines tend to be written in terms of months for ages <= 60 months and years beyond that. Intuitively, the idea being captured here is that the difference between an estimated age of “50 years” and an estimated age of “50 years and 5 months” is unlikely to be clinically relevant, but the difference between an estimated age of “33 months” and an estimate age of “38 months” is more likely to be clinically relevant.

1 Like