REST api example for decode a Base64 data
Hi all,
It's me again ๐. In the pervious article Writing a REST api service for exporting the generated FHIR bundle in JSON, we actually generated a resource DocumentReference, with the content data encoded in Base64
.png)
Question!! Is it possible to write a REST service for decoding it? Because I am very curious what is the message data talking about๐ค๐ค๐ค
OK, Let's start!
1. Create a new utility class datagen.utli.decodefhirjson.cls for decoding the data inside the DocumentReference
Class datagen.utli.decodefhirjson Extends%RegisteredObject
{
}2. Write a Python function decodebase64docref to
a. loop through the FHIR bundle
b. find out the resource DocumentReference
- get the 1st element in the content
- get the attachment from the content
- get the data from the attachment
c. decode the data by Base64
(this part I asked Chat-GPT to help me๐๐คซ)
Class datagen.utli.decodefhirjson Extends%RegisteredObject
{
ClassMethod decodebase64docref(fhirbundle = "") As%String [ Language = python ]
{
# w##class(datagen.utli.decodefhirjson).decodebase64docref()
import base64
import json
def decode_discharge_summary(bundle_json):
"""
Extracts and decodes the Base64-encoded discharge summary note
from a FHIR Bundle containing a DocumentReference.
"""for entry in bundle_json.get("entry", []):
resource = entry.get("resource", {})
if resource.get("resourceType") == "DocumentReference":
# Traverse to the attachment
content_list = resource.get("content", [])
if not content_list:
continue
attachment = content_list[0].get("attachment", {})
base64_data = attachment.get("data")
if base64_data:
decoded_text = base64.b64decode(base64_data).decode("utf-8")
return decoded_text
return None
# Example usage
# Load your FHIR Bundle JSON from a file or object
#with open("fhir_bundle.json", "r") as f:
# fhir_bundle = json.loads(f)
if fhirbundle=="":
rtstr=f"โ ๏ธ No input found - JSON string is required."
jsstr={"operation_outcome" : rtstr}
return json.dumps(jsstr, indent=2)
fhir_bundle = json.loads(fhirbundle)
decoded_note = decode_discharge_summary(fhir_bundle)
if decoded_note:
#print("๐ Decoded Discharge Summary:\n")
#print(decoded_note)
rtstr=f"๐ Decoded Discharge Summary:\n {decoded_note}"else:
#print("โ ๏ธ No DocumentReference with Base64 note found.")
rtstr=f"โ ๏ธ No DocumentReference with Base64 note found."
jsstr={"data" : rtstr}
return json.dumps(jsstr, indent=2)
}
}
For testing this function, I try do some trick, which is making use of the function genfhirbundle to generate FHIR bundle in JSON string, in the pervious article Writing a REST api service for exporting the generated FHIR bundle in JSON.
Let's generated a FHIR bundle and store into a variable jsonstr
set jsonstr=##class(datagen.utli.genfhirjson).genfhirbundle(1)The test the decode function decodebase64docref with the jsonstr
w##class(datagen.utli.decodefhirjson).decodebase64docref(jsonstr).png)
OK ๐ Looks good. Now I can read the decode message.
Now, go back the pervious and pervious article Writing a REST api service for exporting the generated patient data in .csv
We would like to add a new function and update the route for the datagen.restservice class.
1. Add a new function DecodeDocRef, which is expecting to handle the FHIR bundle attached in the body in JSON format.
i.e. In this case, we are expecting a POST.
the body content is packaged as %CSP.BinaryStream by default and stored in the variable %request.Content, so we can use the .Read() function from the class %CSP.BinaryStream to read the BinaryStream
ClassMethod DecodeDocRef() As%Status
{
// get body - json string#dim bistream As%CSP.BinaryStream =""set bistream=%request.Contentset jsstr=bistream.Read()
//decode the Document Reference dataw##class(datagen.utli.decodefhirjson).decodebase64docref(jsstr)
return$$$OK
}
2. Then we add a route for the REST service and compile๐
<Route Url="/decode/docref" Method="POST" Call="DecodeDocRef" />the updated datagen.restservice class will look like the following.
.png)
Great!! That's all we need to do!๐
Let's test in postman!!
POST the following path
localhost/irishealth/csp/mpapp/decode/docrefwith the following body ( I simplified FHIR bundle, you may test the full one๐)
{
"resourceType": "Bundle",
"type": "transaction",
"id": "98bfce83-7eb1-4afe-bf2b-42916512244e",
"meta": {
"lastUpdated": "2025-10-13T05:49:07Z"
},
"entry": [
{
"fullUrl": "urn:uuid:5be1037d-a481-45ca-aea9-2034e27ebdcd",
"resource": {
"resourceType": "DocumentReference",
"id": "5be1037d-a481-45ca-aea9-2034e27ebdcd",
"status": "current",
"type": {
"coding": [
{
"system": "http://loinc.org",
"code": "18842-5",
"display": "Discharge summary"
}
]
},
"subject": {
"reference": "9e3a2636-4e87-4dee-b202-709d6f94ed18"
},
"author": [
{
"reference": "2aa54642-6743-4153-a171-7b8a8004ce5b"
}
],
"context": {
"encounter": [
{
"reference": "98cd848b-251f-4d0b-bf36-e35c9fe68956"
}
]
},
"content": [
{
"attachment": {
"contentType": "text/plain",
"language": "en",
"data": "RGlzY2hhcmdlIHN1bW1hcnkgZm9yIHBhdGllbnQgOWUzYTI2MzYtNGU4Ny00ZGVlLWIyMDItNzA5ZDZmOTRlZDE4LiBEaWFnbm9zaXM6IFN0YWJsZS4gRm9sbG93LXVwIGluIDIgd2Vla3Mu",
"title": "Discharge Summary Note"
}
}
]
},
"request": {
"method": "POST",
"url": "DocumentReference"
}
}
]
}.png)
Works well!!!๐๐
Thank you very much for reading. ๐
Comments
To can get a base64 encoded value from JSON DynamicObject into a stream you don't need to write any conversion code using:
Set stream = jsonObject.%Get("data", , "stream<base64")
Bonus: this works with any data length, is not limited to the IRIS max string size as in the above article.
wow!!! Thanks for sharing!!! It is really helpful!!!โบ