Note: This is reformatted material from a poster showing work in progress. In 2011 we plan to publish detailed descriptions in form of a proper open access paper and to release a demonstrator implementation as open source. If you need to quote this work before the paper is available, then the reference is title and authors as below, with the addition that it was poster at Termkonferens 28-29 September 2010, Skövde, Sweden. Available at http://www.imt.liu.se/~erisu/2010/EEE-Poster-multipage.pdf
REST Based Services and Storage Interfaces for openEHR Implementations E Sundvall, M Nyström, M Sandström, M Eneling, H Örman, D Karlsson Department of Biomedical Engineering, Linköpings universitet, Sweden
Abstract and Objective A lack of open, modular service implementations for openEHR makes it harder for newcomers to experiment with and learn about openEHR. We are addressing this in an educational EHR environment (LiU EEE). Some of our approaches are likely of value to other openEHR implementations and may also contribute to the upcoming openEHR service model specifications. The main contribution of this work is the formalization of the openEHR storage, retrieval and version-handling semantics into a Representational State Transfer (REST) architectural style framework that can be used as a service interface. The modular design using REST principles, (initially implemented using Java Restlets) makes it easy to e.g. test, distribute, cache and loadbalance the system using ordinary web server technology. Another contribution is a generic database interface for basic often recurring tasks and example implementations for different types of database backends. Keywords: openEHR; REST; Medical Informatics; Medical Records Systems, Computerized.
REST - Web principles The term "representational state transfer" (REST) was used in the doctoral dissertation [2] of Roy Fielding, one of the authors of the Hypertext Transfer Protocol (HTTP) specification. • Predefined "verbs" (GET, PUT, POST, DELETE) • ... act on "resources" identified e.g. by URIs • Resources can receive and return different "representations". E.g. xml-dialects (openEHR, RDF), html, json, protobuf, plain text, serialised java objects etc.
URI structure and example scheme://user:
[email protected]:8080/path/to/file;type=foo?name=val#frag \_____/ \_________/\___________/\__/\_______/\__/\_______/\_______/\___/ | | | | | | | | | scheme userinfo hostname port path filename param query fragment \________________________/ (matrix) authority Example: http://www.google.se/search?q=openehr&ie=utf-8&oe=utf-8
A view from a template tool.
Templates are use-case specific, as opposed to the more general archetypes. Some (non-mandatory) parts from contained archetypes can be set to “zero ocurrence” (gray below). Other parts can be set to mandatory or to preset usecase specific defaults.
Introduction
Archetypes contained and constrained in a template
There is a stated ambition within the openEHR specifications to publish a service model (SM) in addition to the already specified reference model (RM) and archetype model (AM) [1], but there is not yet any public specification available. A SM potentially makes it easier for beginners to understand and to start to experiment with software for openEHR. It may also make it easier to focus projects only on parts of an EHR system, like user interfaces or scalable storage.
Methods and Results We studied the openEHR specifications and translated the semantics of EHR content storage and retrieval into the constructs available in a REST [2] architecture, e.g. suitable URI patterns for a set of HTTP GET, PUT and POST operations. The path structures and EHR-URIs from the openEHR specifications [1] lend themselves well to REST. The permanent nature of versioned objects also fits the resource orientation central to REST architectures. Depending on usage scenario, database backend preferences will of course differ; thus we created a minimalistic database interface that provides some pre-parsed keys central to indexing. The HTTP calls are handled using Java Restlets [3] that call the database interface. Our first database implementations use XQuery [4] enabled XML databases and are aimed at clinical scenarios where the main usage is to store and retrieve compositions for individual patients (i.e. normal clinical use). Archetype Query Language (AQL) can be used to query patient data. For e.g. epidemiological use cases we are working on other storage implementations using traditional RDBMSs and distributed systems like Hadoop [5]. The openEHR XML format is currently used as data format in the REST HTTP calls and we have used XSLT and XQuery to transform output to HTML (for web browsers) and KML. KML can be used in Google Earth for patient overview experiments [6].
Discussion Other data formats than XML (like JSON) are also possible, and thanks to REST architecture principles the service URIs and the HTTP calls will remain the same, with exception of declared mime-type. Other implementation languages than Java for the REST based components in the environment are also possible. Any programming language capable of sending and receiving HTTP calls can be used. Our experiences with a REST approach to openEHR EHR services will be available as input to the openEHR specification process and could be a starting point for a REST based SM Implementation Technology Specification for openEHR. Our implementation will be released as Open Source software. This work was partly funded by the Swedish National Board of Health and Welfare.
Example screen form building blocks
An initial space-inefficient version autogenerated from the template on the right. The form would benefit from manual layout simplification and redesign, but having sematically valid building blocks to start from speeds up the GUI creation process.
References 1. 2. 3. 4. 5. 6.
Beale T, Heard S. openEHR Architecture: Architecture Overview. London: 2008. http://www.openehr.org/releases/1.0.2/architecture/overview.pdf Fielding R. Architectural styles and the design of network-based software architectures. 2000. http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm Restlet Lightweight REST framework, http://www.restlet.org/ XQuery W3C Recommendation, http://www.w3.org/TR/xquery/ Apache Hadoop, http://hadoop.apache.org/ Sundvall E, Nystrom M, Forss M, Chen R, Petersson H, Åhlfeldt H. Graphical Overview and Navigation of Electronic Health Records in a Prototyping Environment Using Google Earth and openEHR Archetypes. Stud Health Technol Inform. 2007; 129:1043-1047. http://www.imt.liu.se/~erisu/2007/Sundvall_Medinfo2007_paper.pdf
Contribution Builder purpose: Lowering entry-barrier, simplify development by allowing incremental learning (also via examples) and assist in detect misunderstandings & errors early. URIs contain .../contributionBuilder/{composerId}/{ehrId}/... e.g. http://localhost/contributionBuilder/dr_who/1234567/generateContributionBuildID The generated ID serves as a temporary "writing area" where e.g. compositions can be added(PUT), changed(POST), read(GET) or deleted(DELETE) under URIs like /contributionBuilder/{composerId}/{ehrId}/{tempContributionId}/{tempObjectId}/… Parameters regarding versioning etc can be given via the URI matrix and/or query. Example: .../contributionBuilder/dr_who/1234567/b734db36-30a7-43d6b9ec-51cb389871b6/vital-signs;change_type=creation;object_type=COMPOSITION?lifecycle_state=incomplete… Initial content (intended to later be modified e.g. by a GUI) can be loaded from previous EHR content, or be loaded from a prototype document. Optionally the prototype can be run through engines like Freemarker or Velocity Example: .../load-freemarker-prototype={prototype-uri};change_type=creation?optional-param1-to-prototype-engine=value1... A "rich/fat" client can have it's own internal contribution builder and commit the entire contribution in one step. Clients can reuse the REST semantics and the EEE components internally to make development and maintenance easier. Internal contribution builder can reduce network traffic and server load and provide faster decision support response in GUI etc.
Trigger Handlers can use event stream frameworks or message brokers like Apache ActiveMQ (not REST) that allow subscription based on filters, e.g. archetypes used, terminology codes used in data, EHR ID etc. Messaging via STOMP, JMS, XMPP, REST, WS-notification interfaces allow clients using e.g. Java, C, C++, C#, Ruby, Perl, Python, PHP, ActionScript/ Flash, Smalltalk. Trigger listeners can then access further, more detailed, info via additional GET calls (Classical example: Look up allergies and interactions during medication perscription.)
It can also store data temporarily if network is unavailable (e.g. in mobile applications) A design goal is to make the Contribution builder embeddable in GWT (Google Web Toolkit). Probably not all validators/converters though...
Single EHR access usecase: URIs always contain EHR ID .../ehr/{ehrId}/... e.g. http://localhost/ehr/1234000/56780007@latest_version http://localhost/ehr/1234000/AQLQuery/... - DB query access can be restricted to the EHR identified in the URI - Easy access logging & interpretation.
To make decision support modules reusable between openEHR REST systems, use pure AQL-Query and standard resources (e.g. Versioned object). Don't let reusable trigger listeners read via custom resources and don't let them use queries containing native query languages (e.g. Xquery).
The temporal relation between versioned objects (e.g. Compositions and Folders) and Contribution objects in openEHR
Image source: openEHR Architecture Overview [1]
Queries spanning multiple records are not graphicaly illustrated in this poster. They first follow basically the same pattern as for single access queries regarding translation etc. But because from the router entry point (described in the URI) we already know that we might want to access many records, we can direct the query to a slave database copy using a system suitable for demanding population queries. One prime candidate is Apache Hadoop (an open source map-reduce framework). The timestamped “append only”-principle in openEHR semantics makes database replication easier.
Aggregate EHR access usecase: URIs and connections (not illustrated above) can look almost as single access queries (if specific records are requested) but they can also be more general and access many records. e.g. using URIs like http://localhost/multi/AQLQuery/… - Example usage: Research & statistics - Additional requirements: Ethical approval needed? Anonymization? Log analysis and access control will likely require analyzing query semantics in more complex ways than in the simpler single EHR access usecase. By separating the usecases, the implementation and optimization of the more common and often more time-critical single access usecase is simplified.
Note: This is reformatted material from a poster showing work in progress. In 2011 we plan to publish detailed descriptions in form of a proper open access paper and to release a demonstrator implementation as open source. If you need to quote this work before the paper is available, then the reference is title and authors as on page one, with the addition that it was poster at Termkonferens 28-29 September 2010, Skövde, Sweden. Available at http:// www.imt.liu.se/~erisu/2010/EEE-Poster-multipage.pdf
Note: This is reformatted material from a poster showing work in progress. In 2011 we plan to publish detailed descriptions in form of a proper open access paper and to release a demonstrator implementation as open source. If you need to quote this work before the paper is available, then the reference is title and authors as on page one, with the addition that it was poster at Termkonferens 28-29 September 2010, Skövde, Sweden. Available at http://www.imt.liu.se/~erisu/2010/EEE-Poster-multipage.pdf
Translation of AQL-queries The query implementation approach in LiU EEE is to first translate the clinically targeted AQL-queries to other native storage targeted query languages such as SQL or XQuery and then run query. This allows us to use powerful native query optimizers available in most databases. For recurring requests, AQL-queries translated to native stored procedures can be used to improve performance. EEE's initial tool used for AQL-parsing was implemented in JavaCC and the initial native target query language was XQuery. To speed up implementation and execution of queries that don’t need to be standardised and reused between systems we also allow embedding AQL within the native queries. On the next page examples show AQL embedded in XQuery. AQL does not yet specify any return format, we are suggesting some and for embedded AQL, XQuery’s very flexible return clause can also be used to return custom formats. An EEE storage implementation storing data as RDF might instead translate AQL to SPARQL. The AQL result can also be embedded in a SPARQL query instead of in an XQuery.
Image source: openEHR Architecture Overview [1]
The hierarchical structure of openEHR (colour coded as above)… EHR > Compositions (versioned) > Sections > Entries > Data structures > Values
...provides paths that are convenient for queries, data processing etc. ehr://1234567/87284370-2D4B-4e3d-A3F3-F303D2F4F34B@latest_trunk_version/ content[openEHR-EHR-SECTION.vital_signs.v1]/ items[openEHR-EHR-OBSERVATION.heart_rate-pulse.v1]/ data/events[at0006]/data/items[at0004]/value/magnitude Example AQL queries. More user friendly query-building tools would within the [brackets] show the human readable names from the archetypes, in the local language of choice, instead of language independent at-codes like “at0003”.
AQL in xQuery in XHTML using custom EEE-tags Composition list DateLabelSettingClinician {let $aqlResult := SELECT c FROM Ehr [uid=$ehrUid] CONTAINS COMPOSITION c for $comp in $aqlResult order by $comp/context/start_time/value/text() return {$comp/context/start_time/value/text()} ! ! {$comp/name/value/text()} {$comp/context/setting/value/text()} {$comp/composer/name/text()} }
Graphical patient overview in a Google Earth based prototype environment [6]