Authoring FHIR Resources
- 1 FHIR methodology: Developing a resource
- 1.1 Introduction
- 1.2 Creating a Resource
- 1.3 Tooling Requirements
- 1.4 Resource definition
- 1.5 Getting started
- 1.6 Development Process
- 1.7 Concept Domains
- 1.8 Design Considerations
- 1.9 Notes
- 1.10 Example
- 1.11 Message Events
- 1.12 Known To Do for this guide
FHIR methodology: Developing a resource
This document outlines the steps involved in developing a resource for FHIR. It covers both the technical steps required to produce a resource, and the governance over the process.
Creating a Resource
The first step is to get approval for the resource. Each resource that exists must first be approved by the FHIR governance committee (for now, the governance committee is the MnM project team, but eventually this will be a TSC sub-committee). A proposal to the committee must consider the following things:
- Is the resource scope well described?
- What is the scope of the resource? The scope should ideally broad enough to meet the potential needs of a wide spectrum of users (inpatient + community, individual & public health, human & veterinary, all countries & realms). If covering such a broad spectrum is not possible, the space needs to be segregated such that multiple non-overlapping resources can cover the space
- What other resources will it depend on? What is not in scope for the resource?
- Will other resources are envisaged to depend on it?
- Does the resource overlap with other resources? (i.e. cover the same elements or be associated with the same extensions as)
- What are the target market/implementation focuses for the resource
- What is life cycle of the resource? Does it have a stable id?
- How do the restful transactions match the life cycle of the resource?
- Does the proposed resource have a status field? How does the status field relate to the life cycle?
- What message events does this resource need defined, if any?
- Is this resource an order or other intention that could be fulfilled by other resources? Which ones? What does the fulfillment cycle look like?
- Which committee will be managing this resource?
Generally, the governance committee is looking for stability, for proof that the committee has thought through the implications of the multiple frameworks that FHIR supports, and to prevent the same content being modeled in different ways for no good reason. The committee is also responsible for ongoing QA of resources, and can withdraw permission to publish a non-normative resource, or reassign the ownership of a resource.
Once approval has been gained, the committee can build the resource definition
The following tools are required to develop resources for FHIR:
- A Java Runtime Environment 1.7 (to run the build process)
- A .CSV (comma separated spreadsheet) editor to edit the definitions. Excel is used by the core team, but is not required
- Enterprise Architect v 7.6 to edit the UML diagrams
- An XML editor. XMLSpy is recommended, or another schema driven editor is useful, but any XML editor can be used
- A subversion client is required for version control
- For FHIR tooling development, a Java development environment is required
In addition to these tooling prerequisites, to develop a resource, you will need a subversion username and password, and a resource name.
To define a resource, 4 different things must be built:
- A spreadsheet that contains the master resource definition
- A UML class diagram that shows the class based definition of the resource
- An HTML fragment that contains additional notes required to explain the resource definition
- An XML example for the resource
- Additional mapping files and/or translation files may also be created, but are not required.
- Check out org.hl7.fhir from the subversion repository at https://svn.codespaces.com/healthintersections/fhir/
- In the root directory, execute publish.bat to check that you have the required build environment - it should report that everything builds successfully (on unix systems [how to run publish process])
- Open /publish/introduction.htm and check that it displays ok
- In the source directory, create a subdirectory with the name of the resource, all in lower case - this is hereafter known as [name]
- Copy the contents of source/templates into this directory, and rename all three files to the same name as the directory (all lower case)
- Add you resource name - in lower case - to the resources section of the publish.ini file in the root directory. Also, add it to the appropriate section in section.htm
- Open the [name].csv file, and edit the contents. In the first column, replace "Template" with the name of the resource (using correct case, hereafter known as [Title])
- Update the template definitions and comments in the other columns appropriately, but do not change the cardinality, conformance, type, or concept domain columns for the existing rows. Then save the file
- Open the [name ].xml file, and replace the 3 occurrences of "Template" with [Title] (the schema doesn't exist yet, so the XML editor might complain about that. Ignore it)
- Open enterprise architect, open the version controlled project file (see instructions - TODO.), check out the "Class Model" Package.
- and copy the Template package, and then paste it as a copy. Now rename the package to [Title], along with any other occurrences of the word "Template". Check in the Class Model package
- Open the diagram, and export it as an image to [name].png in the images subdirectory.
- Execute publish.bat again, and go back to /publish/introduction.htm, and check that your resource appears in the right place.
You are now ready to start developing the actual resource content across the 4 source files. Note that you can leave all but the steps 1-3 to the governance committee if you are happy to leave drafting resource content until after you have approval for the resource. You cannot check in changes to publish.ini/sidebar.htm until approval for the resource has been granted.
The master definitions of the resource are found in the .csv file. This contains a series of columns that define the content of the resource.
|Element||The full path of the element (defines the element - see below)|
|Card.||Minimum and maximum Cardinality. Elements that have a max cardinality > 1 should still
have a singular name. Note that the usual cardinality combinations are 0..1, 1..1, 0..* and 1..*. Other values for both the lower and upper limit are allowed, but should be based on genuine limits, not arbitrary conformance-type limits.
|Conf.||Conformance (see Control Codes). conformance which is tightly tied to the cardinality. Note that an element with a 0..1 cardinality shouldn't be mandatory, while an element with 0..* cardinality may be optional, conditional, or mandatory|
|Type||[Conditional] The type of a data element - may be from the data types, or
A type must be assigned if the element has no children defined, else a type must not be assigned
Multiple types can be indicated, seperated by a "|". If more than one type is listed, the element name must terminate with "[x]". If the type is Resource, one or more resource types must be listed as a parameter, or "Any" for any kind of resource.
|Concept Domain||[Conditional] For types of code, Coding, or CodeableConcept, a concept domain must be defined. Concept domains may be bound as part of the FHIR specification - see below|
|Must Understand||[Optional] Whether a receiving application must understand the element (note that must understand
isn't quite the same as must support - if an application understands the element by insisting on one fixed value, this is acceptable)
|Short Name||The definition used for the resource in the XML definitions - limited in length by the available space in the definitions|
|Definition||Formal definition for the meaning of the element. This must follow definition good practices – See below.|
|Requirements||[Optional] Underlying requirements that this element is defined to meet|
|Comments||[Optional] Additional user focused comments - clarifications, explanation of how to use the element, notes on how not to use it.|
|Condition||[Conditional] if the conformance code is "Conditional", this specifies what the condition is|
|RIM Mapping||RIM mapping for the element. See below|
|v2 Mapping||[Optional] where this element comes from in v2 messages. Multiple mappings may be provided|
|To Do||[Optional] Committee notes to implementers about future things that are planned (published)|
|Committee Notes||[Optional] Private committee notes - not published|
The most important column is the first one, which defines the structure of the resource. The first row of the first column defines the formal title of the resource used throughout the FHIR build process. Every row from then on must start with [Title]. The second row is always [Title].id, which is the master identifier of the resource that never changes. From there on, the values of the rows take the form of [Title].x.y where the dotted notation indicates structural containment. For instance, [Title].id is the id element in the resource [Title], and [Title].section.name is a name element inside the section element of the [Title] resource element. A path can never be used without defining it first. So [Title].element.name can only be used after [Title].element. The last two elements in a resource are always [Title].extensions and [Title].text, as defined in the template.
Names used for resource elements must follow the following rules and guidelines:
- use lowerCamelCase
- U.S. English (spelled correctly!)
- Expressed as a noun, with a preceding adjective where necessary to clarify the semantics
- Use the “most broadly recognized” industry term for the object that is unlikely to be mistaken for a different element.
- Use abbreviations only where extremely well understood by the entire target market. Only the first letter of an abbreviation should be uppercase
- Use different names for different elements within the hierarchy unless the semantic is the same in different context. (E.g. using “.name” for “sponsor.name” and “contact.name” is ok if the meaning of “name” is consistent for both sponsor and name.)
- Be concise (differentiation of semantics through the name is only necessary with other elements in the resource. Full semantic description is in the definitions.)
Elements should be ordered roughly in terms of importance, with related concepts grouped together.
The base spreadsheet only has columns for mapping to the RIM and v2. Many other mappings can be done, but will be found in other spreadsheets (details to be provided).
In all but a few rare circumstances, elements with a data type of code, coding, and codeableConcept should have a concept domain assigned. This provides a hook for the terminology methodology and implementation tools. Any concept domain defined must be entered in /terminologies/concept- domains.csv, along with a definition and binding information. The binding information should be filled out according to this table:
|Concept Domain||The name of the concept domain as used in the resource definitions|
|Definition||A formal definition for the concept domain, following good definition practices. See below|
|Binding Type & Binding||The type of binding defined in FHIR. Possible values:
Todo: methdology + grammar
A core tenant of FHIR is that resources should be simple, stable, and easy to use. Generally, the following guidelines apply to defining resources:
- Define the resource scope, and target market clearly
- Resources are subject to ballot. All of FHIR is balloted as a single pack (a la v2). A difference analysis will be available to help with the ballot cycle
- When designing resources, pre-existing designs that should be consulted are:
- v3 Domain models
- CDA, Consolidated CDA story and other implementation guides (and IHE specifications)
- v2 segments
- openEHR Archetypes on http://www.openher.org/ckm
- National repository definitions (possible sources: S&I (including the CEDD), UK NHS, Canada Health Infoway, Singapore LIMs, NEHTA (Australia)) - beware of local variations
- Conciseness is a Primary virtue. Every word must count, since everyone has to read it.
- The element definitions include a requirements slot. This is not mandatory, and can be hard work, but can also be used to make the resource more maintainable. Note that in FHIR, negative ballot comments can't be ruled out of scope if they challenge a missing or unclear requirements.
- All elements and extensions defined by HL7 committees must have a genuine RIM mapping.
- Structural re-arrangements to the resources are very difficult if not impossible (including cardinality - see below). Path based navigation must not be changed (=broken)). Therefore, considerable thought should go into data structure. Specific considerations are listed below
- Event data that goes in the resource: enduring semantically significant event metadata i.e. pathologist approving lab report, prescriber of medication - need to be maintained in band with the data, not somewhere else
- todo : status, request/fulfillment (there will be other "pointer" resources for request/fulfillment, + pattern for event history on resources that have events (and usually status)
A key part of the design process is that the resources should the define the data elements that everyone needs, and leave the rest of the data elements to extensions - the committee can define and publish extensions. The point of committees defining extensions is that uncommonly encountered use cases can be kept in extensions, and all implementers are not forced to deal with them (this is a big part of the perceived implementation difficulty associated with HL7 standards). Therefore one significant part of the process of building a resource is deciding what elements to put in the resource, and what to put in extensions. Data elements are candidates for being in the base resource if:
- They are not specific to only one or two countries.
- If the data elements are in the 80%: i.e. something that 80% of implementers will encounter and/or need - not 80% of the cases that occur to all implementers (this is about preventing work flow variations from complicating the model)
- Any implementer must understand the content in order to understand the core problem (i.e. can't be ignored)
- If modeled in all other relevant specifications (particularly, v2, v3, openEHR)
Extensions are a legitimate way for committees to define content. While committees should not define extensions that must be understood, there is no reason for committees not to define extensions. Note that in FHIR, ballot comments that something is in an extension and not a model can be ruled out of scope or non-persuasive if substantial evidence is not provided that the above criteria are met. Committees may subsequently elevate extensions to full resource content (implementation implications of this are discussed in the standard). It is expected that most, if not all, useful implementation profiles will include the use of extensions.
Changing cardinality is significant to implementers. The following guidelines apply:
- If an element has multiple cardinality in some use cases, or there is a prospect it might be made multiple cardinality in the future, and when there is no clear differentiation of the primary case, make it multiple cardinality now
- v3 has many cardinality changes in cascading models. in FHIR, most cardinality changes occur in conformance statements and don't change the resource
- if making something multiple cardinality after it wasn't, introduce a new element, define the original as part of the list in the definitions, and clearly describe how the primary is differentiated.
todo: put something here from vocabulary. Specifically, we’re looking for: short, non-tautological using broadly understood terms, with examples (usually 3-4, unless it’s bound or something simple like a date). Definitions must clearly distinguish an element from other elements, including extension elements.
Choosing a data type
The following table defines the data types available, and provides some notes concerning their use.
|string||A simple string (=v3 ST)||Should be known to be short, and no prospect of containing paragraphs or structure or formatting|
|Narrative||xhtml structure||Don't use except where it appears in all resources|
|Attachment||Multimedia Attachment (=v3 ED)||For complex narrative that may have paragraphs, structure, or formatting, or not be text based at all (image, video etc)|
|code||A simple code (~v3 CS)||Simple code where the list is defined by the FHIR infrastructure, the resource definition, or by some fixed external reference (usually ISO or W3C)|
|Coding||A defined code (~v3 CV)||A direct reference to a concept in a terminology. Use where the content model is managing the issue of text equivalence, and translations across multiple fields directly|
|CodeableConcept||A full concept (~v3 CD)||Use for a simple equivalent of CD/CE|
|Choice||A choice from a questionnare||a code from a code/description list, where there is no formal terminology underlying the list|
|dateTime||a fixed instant(=v3 TS)||System times, always known to the second|
|humanDate||a date with variable precision(=v3 TS)||Year, Year + month, Year + month + date, or a dateTime - use for any dates taht might come from humans|
|Schedule||A set of times (~v3 GTS)||For specifying a schedule (a tamed GTS)|
|integer||A simple integer (=v3 INT)||only a simple integer - for structural values only (like query result count)|
|Quantity||A measured/measurable amount (~v3 PQ/CO/MO/IVL)||Use where there is a value with human units, that may be coded. It may be possible to use a more specific variant:|
|Duration||An amount of time (~v3 PQ)||Fixes to units of time coded in UCUM|
|Count||A simple count (~v3 PQ/INT)||Fixes the quantity to a simple count of whole numbers|
|Money||A currency amount (~v3 MO)||Fixes units to a currency|
|Interval()||An interval (=v3 IVL/URG)||A range (low + high). If an element can be either a fixed interval or a duration, allow both types. Usual types parameters can be Quantity or humanDate, but integer, decimal, and dateTime can also be used|
|Ratio||numerator/denominator (=v3 RTO)||Same usage as v3 ratio. Usually just used as a choice of possible data type on observations|
|uri||A uri (~v3 URL)||A uri. (urn or URL). Usually used in the data types, not in resources|
|id||A simple id||This is not properly scoped. It's used where the scope implicitly implies the meaning - resource ids, or internal references. No use in general resource content|
|Identifier||A known identifier (~v3 II)||An identifier. Same scope as II|
|HumanId||A human assigned identifier (see v3 identifier pattern) (=v2 CX)||In addition to the actual Id, has a type, a period, and an assigner. Use for human assigned identifiers|
|Resource()||A reference to another resource||You can specify one or more resource types in the parameter (or "Any")|
|HumanName||A human assigned name (=v3 EN)||use as for v3 EN / v2 XPN / XON|
|Address||A postal address (=v3 AD)||Use as for v3 AD / v2 XAD|
|Contact||Contact details (=v3 TEL)||Use as for v3 TEL / v2 XTN|
In addition to these data types, there's a few other legal data types that are not expected to be used anywhere in a resource.
The information defined in the .csv file will all appear in the specification but are all specific to an element, and some are only published in the formal definitions. To help the user with implementation, a set of concise additional notes is found under each resource definition. These notes may discuss how to use a resource, why it doesn't contain things, the relationship between fields, etc. these notes are defined by editing [name].htm
In addition, [name].htm contains further usage notes, and any search parameters that must defined for the resource.
The final part of building a resource is to hand edit an example. The data in the example should illustrate aspects of building and using the resource and is a useful way of double checking the resource definitions. Ideally it should be appropriate from a business/clinical perspective. However, fully exercising the resource is more important.
Resources may also have specific message events defined for them. For now, this is done in source/messaging.htm.
Known To Do for this guide
- Need a section on how to author extensions, as that will need to happen as part of development. Hints on what sorts of extensions should be created – e.g. commonly used v2 elements, v3 elements, etc.
- Need a section providing guidance on how to structure resources, particularly approaches that will simplify future growth and ability to attach extensions.
- Need guidance on when selection of a vocabulary is appropriate.