Ironhide

The data transformer

Created by Andrew Tropin and contributors

Content

  1. Introduction
  2. Solution description
  3. Implementation details

Introduction

What is data?

In our case it's a tree-like structure,

anything isomorphic to json/xml

Problem

Different systems have different data models and it's often necessary to keep data in sync

Who is affected?

Interaction

  • between frontend and backend
  • with external/legacy system
  • of different technologies
  • ...

Example

fronted:



        {"name" : "Alexander Ivanov"}

				  

backend:


{
  "name": [{
    "given": [
      "Alexander"
    ],
    "family": "Ivanov"
  }]
}
          

Existing solutions

  • Programming languages (python, clojure, etc)
  • DSLs (selmer, xslt, boomerang)
  • Libraries and utilities (awk, sed, hadoop)

Example

Selmer:

    {% for item in items %}
  • {{item}}
  • {% endfor %}

Solutions similarities

They all have:

  • data
  • language
  • runtime

Objectives

Create a language with following properties:
  • bidirectional
  • data-driven
  • runtime agnostic

Solution description

Rules

The heart of transformation

          :rules [{:form [:ihm/name<->vector [0]]
                   :fhir [:name [0] :given [0]]}

                  {:form [:ihm/name<->vector [1]]
                   :fhir [:name [0] :family]}

                  {:ih/value {:fhir [:default-gender]}
                   :fhir [:gender]}]
          

Paths

Addressing the element


[:name [0] :given [0]]

[:telecom [:* {:system "phone"}] :value]

;; {:name "Firstname Secondname"}
[:name :ihs/str<->vector [0]] ;; => [["Firstname"]]
          

Multidimensional figures

Multidimensional figures

Micros

Do not copypaste

          (microexpand-path

           {:ih/micros {:ihm/name [:name [:index] :given [0]]}}

           [{:ih/micro :ihm/name :index 10}])
          ;; => [:name [10] :given [0]]
          

Values

Missing some data?(


          {:ih/values {:person/name "Name not provided by the form"}

           :ih/rules  [{:form     [:name]
                        :form-2   [:fullname]
                        :ih/value {:form-2 [:ih/values :person/name]}}]}

          

Sights

  • str<->ast
  • camel<->kebab
  • suitable?

Sights

xml<->ast sight example

          
  • str<->ast
  • camel<->kebab
  • suitable?
{"ul": {"li": [{"-class": "cl", "#text": "str<->ast"}, {"-class": "cl", "#text": "camel<->kebab"}, {"-class": "cl", "#text": "suitable?"}]}}

Implementation details

Validation


          (s/def ::path (s/coll-of ::pelem))
          (s/def ::pelem (s/or :mkey ::mkey :sight ::sight :vnav ::vnav))
          (s/def ::mkey keyword?)
          (s/def ::sight sight?)
          (s/def ::vnav
          (s/cat :vkey ::vkey :vfilter (s/? ::vfilter)))

          (s/def ::vkey (s/or :index ::index :wildcard ::wildcard))
          (s/def ::wildcard #(= :* %))
          (s/def ::index nat-int?)
          (s/def ::vfilter map?)
          

Interpreter

Micros

Sights

  • multimethods
  • closures

Question?

@andrewtropin

https://github.com/abcdw

healthsamurai/ironhide