Applying changes from Parameters resource to another FHIR resource?

Hi all,

This is my first post so I will try to be concise as much as possible. As my username suggests, I’m junior developer and project (microservice) I’m working on is using FHIR server. Me and team are not writing any FHIR server related features. We just relay on FHIR to save, sort or update data etc.

I’m currently working on a FHIR Resource called MedicinalProduct . There are other MedicinalProduct-related Resources I deal with, such as MedicinalProductAuthorization , MedicinalProductPharmaceutical etc, but I’ll focus just on MedicinalProduct. Our Solution Architects told us that we are not using all fields and properties but just a subset which they defined.

Two web services I’m responsible for are validation during CREATE and UPDATE. Here by validation I don’t mean on /$validate operation (i.e. once profiling has been done) shorturl.at/pzFJX

My validation entails that some custom business rules are satisfied and not broken. Here is the part of mapping between Domain model and Fhir model, essentail I need to conform to the Domain model (yellow boxes) regarding cardinality and structure of Identifiers, CodeableConcepts etc.

Service for creating (i.e. validation when the MedicinalProduct is about to be created on Fhir) resources is done. I’m receiving a Bundle with MedicinalProduct resource, which can easily be deserialized into Java object org.hl7.fhir.r4.model.MedicinalProduct and I can do whatever I want with it (i.e. apply business rules).

On the other hand when doing an update I will not get a Bundle of Fhir resources such as MedicinalProduct, MedicinalProductPharmaceutical etc, but rather Bundle of Parameters ( shorturl.at/aswI0 ) resources (a lot of them), where each Parameter resources can do any of the FhirPatch operations (shorturl.at/fnCQR) to the MedicinalProduct.

Let’s take as an example ‘productClassification’ and ‘dispensingRequirement’:

Valid ‘productClassification’ that had been created on Fhir can look like this:

"productClassification": [
					{
						"coding": [
							{
								"system": "valid-codeSystem-url-for-dispensation-type",
								"code": "valid-defined-code-for-dispensation-type"
							}
						]
					},
					{
						"coding": [
							{
								"system": "valid-codeSystem-url-for-storage-list",
								"code": "valid-defined-code-for-storage-list"
							}
						]
					},
					{
						"coding": [
							{
								"system": "valid-codeSystem-url-for-characteristics",
								"code": "valid-defined-code-for-characteristics"
							}
						]
					}
				],

If I get Bundle which contain these two Parameters resource, this will place ‘productClassification’ in valid state, after applying following changes:

{
   "resourceType":"Bundle",
   "type":"transaction",
   "entry":[
      {
         "resource":{
            "resourceType":"Parameters",
            "parameter":[
               {
                  "name":"operation",
                  "part":[
                     {
                        "name":"type",
                        "valueCode":"delete"
                     },
                     {
                        "name":"path",
                        "valueString":"MedicinalProduct.productClassification.where(coding.system='valid-codeSystem-url-for-dispensation-type').coding"
                     }
                  ]
               },
               {
                  "name":"operation",
                  "part":[
                     {
                        "name":"type",
                        "valueCode":"insert"
                     },
                     {
                        "name":"path",
                        "valueString":"MedicinalProduct.productClassification"
                     },
                     {
                        "name":"value",
                        "valueCodeableConcept":{
                           "coding":[
                              {
                                 "system":"valid-codeSystem-url-for-dispensation-type",
                                 "version":"1",
                                 "code":"1"
                              }
                           ]
                        }
                     },
                     {
                        "name":"index",
                        "valueInteger":0
                     }
                  ]
               },
            ]
         },
         "request":{
            "method":"PATCH",
            "url":"MedicinalProduct/3081"
         }
      }

   ]
}

Here we first did delete and then insert.

On the other hand if someone tries to do delete operation on path MedicinalProduct.productClassification.where(coding.system=‘valid-codeSystem-url-for-dispensation-type’).coding and then do two inserts on index 0 and 1, then that would be a violation of business rule (broken cardinality), and I cannot send Parameters Bundle to FHIR to apply those changes on MedicinalProduct resource.

There is a large number of combinations what can come through Parameters Bundle and my task is somehow to figure out what those changes want to do the resources (which I fetched from Fhir after have received Parameters Bundle), apply those changes in my service (during runtime) and pass those “updated” resources thorugh validation which already exists and wokrs when the resources is first time created.

In very oversimplified pseudo-code, I need something like this:

    public boolean patchMedicinalProduct(Bundle parametersBundle, String medicinalProductId){

        MedicinalProduct createdResource = fhirRepo.fetchMedicinalProduct(medicinalProductId); //this is valid MedicinalProduct; which had been previously created

        List<Parameters> deleteParameters = ServiceUtils.extractDeleteParameters(parametersBundle);
        List<Parameters> insertParameters = ServiceUtils.extractInsertParameters(parametersBundle);
        List<Parameters> replaceParameters = ServiceUtils.extractReplaceParameters(parametersBundle);
        
        
        for (Parameters deleteParameter : deleteParameters){
            //I need something like this:
            createdResource = applyDeleteParam(deleteParameter, createdResource);
        }

        for (Parameters insertParameter : insertParameters){
            //I need something like this:
            createdResource = applyInsertParam(insertParameter, createdResource);
        }


        for (Parameters replaceParameter : replaceParameters){
            //I need something like this:
            createdResource = applyReplaceParam(replaceParameter, createdResource);
        }
        
        return validationServiceMedicinalProduct(createdResource);
        
    }

'applyParam’ methods should be from org.hl7.fhir. package. I suppose that something like that doesn’t even exists?

The closest I got to something like that can be found here (https://groups.google.com/g/hapi-fhir/c/1fEmWsjSphI) (first three posts) and class HAPI WriteByFHIRPath WIP ($453) · Snippets · GitLab

Very much apologies for longer post.

No apologies needed. Congrats on making a very clear first post :slight_smile:

I believe the HAPI reference implementation already has full support for FHIRPath Patch. Check out this class here: FhirPatch (HAPI FHIR JPA Server 5.7.0-PRE4-SNAPSHOT API)

If you have further questions about how to use it, the best place to ask is the hapi stream on chat.fhir.org.

1 Like