Skip to content

Kodjin Data Mapper

Data Mapper is a part of Kodjin interoperability suite. It is a service that implements data conversion from proprietary and legacy formats to FHIR format. Currently, it supports four types of conversions: JSON to FHIR, HL7v2 to FHIR, C-CDA to FHIR and FHIR STU3 to R4.

Endpoints

  • POST [fhir_base]/$convert-data

  • GET, POST, PUT, DELETE [fhir_base]/templates/[id]

Query parameters

Query parameter Type Status Description
template string implemented The id of the template used for conversion
data json object implemented The actual data to be converted

Overview

  • Data mapper is implemented using Liquid template engine.
  • there're CRUD operations on templates and the ability to store the templates in GitHub repo similarly to the FHIR profiles.

The example of the template

{
        "resourceType": "Patient",
        "id": "{{ PatientId | to_json_string | generate_uuid }}",
        "identifier": [
            {
                "use": "usual",
                "type": {
                    "coding": [
                        {
                            "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
                            "code": "MR"
                        }
                    ]
                },
                "system": "urn:oid:2.16.840.1.113883.19.5",
                "value": "{{ MRN }}"
            }
        ],
        "active": true,
        "name": [
            {
                "family": "{{ LastName }}",
                "given": [
                    "{{ FirstName }}"
                ]
            }
        ],
        "gender": {% if Gender == 'M' -%}
            "male",
        {% elsif Gender == 'F' -%}
            "female",
        {% elsif Gender == 'U' -%}
            "unknown",
        {% elsif code -%}
            "other",
        {% else %}
            "",
        {% endif -%}
        "birthDate": "{{ DOB | add_hyphens_date }}",
        "managingOrganization": {
            "reference": "Organization/2.16.840.1.113883.19.5",
            "display": "Good Health Clinic"
        }
}

Filters

By default, Liquid provides a set of standard filters to assist template creation. Besides these filters, Kodjin Data Mapper also provides some other filters that are useful in conversion, which are listed below.

Hl7v2 specific filters

Filter Description Syntax
get_first_segments Returns first instance of the segments {% assign result = hl7v2Data \| get_first_segments: 'segment1\|segment2\|...' -%}
get_segment_lists Extracts HL7 v2 segments {% assign result = hl7v2Data \| get_segment_lists: 'segment1\|segment2\|...' -%}
get_related_segment_list Given a segment and related segment name, returns the collection of related named segments {% assign result = hl7v2Data \| get_related_segment_list: parentSegment, 'childSegmentName' -%}
get_parent_segment Given a child segment name and overall message index, returns the first matched parent segment {% assign result = hl7v2Data \| get_parent_segment: 'childSegmentName', 3, 'parentSegmentName' -%}
has_segments Checks if HL7 v2 message has segments {% assign result = hl7v2Data \| has_segments: 'segment1\|segment2\|...' -%}
split_data_by_segments Given an HL7 v2 message and segment name(s) as the separator(s), returns the message list split by separator(s).
Note: Each segment separator will be retained as the first segment of each message in the list, while the segments before the first separator (which may be empty) will be retained as the first message in the list without any separator.
{% assign result = hl7v2Data \| split_data_by_segments: 'segment1\|segment2\|...' -%}

C-CDA specific filters

Filter Description Syntax
get_first_ccda_sections Returns first instance (non-alphanumeric chars replace by '_' in name) of the sections {% assign firstSections = msg \| get_first_ccda_sections: 'Problems' -%}
get_ccda_section_lists Returns instance list (non-alphanumeric chars replace by '_' in name) for the given sections {% assign sections = msg \| get_ccda_section_lists: 'Problems' -%}
get_first_ccda_sections_by_template_id Returns first instance (non-alphanumeric chars replace by '_' in name) of the sections by template id {% assign firstSections = msg \| get_first_ccda_sections_by_template_id: '2.16.840.1.113883.10.20.22.2.5.1' -%}

String Filters

Filter Description Syntax
char_at Returns char at position index {{ 'foo' \| char_at: 0 }} #=> 'f'
contains Returns true if a string includes another string {{ 'foo' \| contains: 'fo' }} #=> true
escape_special_chars Returns string with special chars escaped {{ '\E' \| escape_special_chars }} #=> '\\E'
unescape_special_chars Returns string after removing escaping of special char {{ '\\E' \| unescape_special_chars }} #=> '\E'
match Returns an array containing matches with a regular expression {% assign m = code \| match: '[0123456789.]+' -%}
to_json_string Converts to JSON string {% assign msgJsonString = msg \| to_json_string -%}
to_double Converts string to double {{ "100.01" \| to_double }}
base64_encode Returns base64 encoded string {{ decodedData \| base64_encode }}
base64_decode Returns base64 decoded string {{ encodedData \| base64_decode }}
sha1_hash Returns SHA1 hash (in hex) of given string {{ inputData \| sha1_hash }}
gzip Returns compressed string {{ uncompressedData \| gzip }}
gunzip_base64_string Returns decompressed string {{ compressedData \| gunzip_base64_string }}

Math filters

Filter Description Syntax
is_nan Checks if the object is not a number {{ true \| is_nan }} #=> true
abs Returns the absolute value of a number {{ -2019.6 \| abs }} #=> 2019.6
pow Returns the base to the exponent power, that is, base^exponent {{ 3 \| pow: 3 }} #=> 27
random Returns a non-negative random integer that is less than the specified maximum. {{ 100 \| random }} #=> 52
sign Returns either a positive or negative +/- 1, indicating the sign of a number passed into the argument. If the number passed into is 0, it will return a 0. Note that if the number is positive, an explicit (+) will not be returned {{ -5 \| sign }} #=> -1
truncate_number Returns the integer part of a number by removing any fractional digits {{ -34.53 \| truncate_number }} #=> -34
divide Divides first number by the second number and return a double {{ 5 \| divide: 2 }} #=> 2.5

DateTime filters

Filter Description Syntax
add_hyphens_date Adds hyphens to a date or a partial date that does not have hyphens to make it into a valid FHIR format. The input date format is YYYY, YYYYMM, or YYYYMMDD. The output format is a valid FHIR date or a partial date format: YYYY, YYYY-MM, or YYYY-MM-DD. {{ PID.7.Value \| add_hyphens_date }}
format_as_date_time Converts valid HL7v2 and C-CDA datetime to a valid FHIR datetime format. The input datetime format is datetime or partial datetime without hyphens: YYYY[MM[DD[HH[MM[SS[.S[S[S[S]]]]]]]]][+/-ZZZZ]. For example, the input 20040629175400000 will have the output 2004-06-29T17:54:00.000Z. Provides parameters to handle different time zones: preserve, utc, local. The default method is preserve. {{ PID.29.Value \| format_as_date_time: 'utc' }}
now Provides the current time in a specific format. The default format is yyyy-MM-ddTHH:mm:ss.FFFZ. {{ '' \| now: 'dddd, dd MMMM yyyy HH:mm:ss' }}
add_seconds Adds double seconds on a valid FHIR datetime (e.g.2021-01-01T00:00:00Z). Provides parameters to handle different time zones: preserve, utc, local. The default method is preserve. {{ "2021-01-01T00:00:00Z" \| add_seconds:100.1, 'utc' }}

Collection filters

Filter Description Syntax
to_array Returns an array created (if needed) from given object {% assign authors = msg.ClinicalDocument.author \| to_array -%}
concat Returns the concatenation of provided arrays {% assign ethnicCodes = ethnicCodes1 \| concat: ethnicCodes2 -%}
batch_render Render every entry in a collection with a snippet and a variable name set in snippet {{ firstSections.2_16_840_1_113883_10_20_22_2_5_1.entry \| to_array \| batch_render: 'Entry/Problem/entry', 'entry' }}

Miscellaneous filters

Filter Description Syntax
get_property Returns a specific property of a coding with mapping file CodeSystem.json {{ PID.8.Value \| get_property: 'CodeSystem/Gender', 'code' }}
generate_uuid Generates an ID based on an input string {% assign patientId = firstSegments.PID.3.1.Value \| generate_uuid -%}
generate_id_input Generates an input string for generate_uuid with 1) the resource type, 2) whether a base ID is required, 3) the base ID (optional) {{ identifiers \| generate_id_input: 'Observation', false, baseId \| generate_uuid }}
concept_map_translate translates the code from source to target using $translate operation on ConceptMap {{ Code \| concept_map_translate: id: 'icd10-to-icd9, system: 'http://hl7.org/fhir/sid/icd-10-cm', target_system: 'http://terminology.hl7.org/CodeSystem/icd9' }}

Tags

By default, Liquid provides a set of standard tags to assist in template creation. Besides these tags, FHIR Converter also provides some other tags useful in conversion, which are listed below. If these tags do not meet your needs, you can write your own tags.

Tag Description Syntax
evaluate Evaluates an ID with an ID generation template and input data {% evaluate patientId using 'Utils/GenerateId' obj:msg.ClinicalDocument.recordTarget.patientRole -%}
mergeDiff Merge diff JSON on input JSON data. The input data and difference in content should be a valid JSON format. {% mergeDiff msg -%}
<diff json>
{% endmergeDiff -%}

Data-Mapper API

Create a new template

To upload a new template for Kodjin data-mapper through the API, use a POST request to the [fhir_base]/templates/[template_name] endpoint. Where:

  • fhir_base - the base url of Kodjin FHIR Server
  • template_name - a name for identifying the template
  • templates - is a configurable path in Kodjin data-mapper configuration (template used by default Kodjin configuration)

The request body should contain a JSON object with two parameters:

  • type - possible values include: json, html, etc
  • payload - the template code

Starting from Kodjin FHIR Server version 4.4.0, there have been changes to the creation of new templates through the data-mapper API.

Post-processing for json template types.

Templates with a json type will undergo post-processing, while html or other types will not. See details about post-processing in the section below.

How to create a new template:

    {
        "type": "json",
        "payload": "Liquid Template Text"
    }

Example request:

curl --location --request PUT 'https://demo.kodjin.com/templates/example-patient' \
--header 'content-type: application/json' \
--data '{
    "type": "json",
    "payload": "{
        "resourceType": "Patient",
    "id": "{{ msg.PatientId | to_json_string | generate_uuid }}",
    "identifier": [
        {
            "use": "usual",
            "type": {
                "coding": [
                    {
                        "system": "http:
                        "code": "MR"
                    }
                ]
            },
            "system": "urn:oid:2.16.840.1.113883.19.5",
            "value": "{{ msg.MRN }}"
        }
    ],
    "active": true,
    "name": [
        {
            "family": "{{ msg.LastName }}",
            "given": [
                "{{ msg.FirstName }}"
            ]
        }
    ],
    "telecom": [
        {% comment -%} 
            use "[]" to access value if the key contains spaces or other special characters 
        {% endcomment -%}
        {% for p in msg["Phone Number"] -%}
            {
                "system": "phone",
                "value": "{{ p }}",
            },
        {% endfor -%}
    ],
    "gender":   {% if msg.Gender == '\''M'\'' -%}
            "male",
                {% elsif msg.Gender == '\''F'\'' -%}
            "female",
                {% elsif msg.Gender == '\''U'\'' -%}
            "unknown",
                {% elsif code -%}
            "other",
                {% else %}
            "",
                {% endif -%}
    "birthDate": "{{ msg.DOB | add_hyphens_date }}",
    "managingOrganization": {
        "reference": "Organization/2.16.840.1.113883.19.5",
        "display": "Good Health Clinic"
    }
}"
}'

Update a template

To update an existing template for Kodjin data-mapper through the API, use a PUT request to the [fhir_base]/templates/[template_name] endpoint. Where:

  • fhir_base - the base url of Kodjin FHIR Server
  • template_name - a name for identifying the template

The request body should contains an updated template.

Get a template by id

To retrieve a template, send a GET request with the template name that was used to create the template.

How to get a template through API:

curl --location 'https://demo.kodjin.com/templates/example-patient'

Delete a template

To delete a template send a DELETE request with the template name that was used to create the template.

How to delete a template through API:

curl --location --request DELETE 'https://demo.kodjin.com/templates/ADT_X10'

JSON post processing

When a json-type template is rendered or inbound data is transformed using a json-type template, the Data-mapper will apply post-processing to the rendered object. This includes:

  • Removing trailing commas
  • Removing empty objects
  • Removing empty lines
  • Removing repeated objects with the same attributes.

Security

Data-mapper is secured with Role-Based Access Control (RBAC). RBAC scopes follow the SMART on FHIR style. When RBAC is enabled in the Kodjin FHIR Server, the following scopes are needed to work with the Data-mapper:

Security option is enabled by Kodjin's RBAC feature accordingly.

  • user/Datamapper.read
  • user/Datamapper.write