Accelerators
Accelerators are shortcuts that let you write FHIR resources more compactly.
Id accelerator
In FHIR every resource should have an id, and resource references start with a resource type, a slash, and an id (Patient/4, Patient/example, Organization/f201). YamlGen has adopted that syntax: you can define the id of a resource by adding a slash to the top-level key. So Patient/4: is identical to:
Patient:
id: 4
The following YAML produces a patient with id “4”:
Patient/4:
name:
given: John
family: Williams
Path shortcuts
YAML can become verbose when you start nesting. To avoid this, YamlGen allows the use of paths, much like the ones used in FHIRPath. You can dot into the details directly:
Patient/example:
meta.profile: http://acme.org/fhir/Patient
name.given: John
which is equivalent to:
Patient:
id: example
meta:
profile: http://acme.org/fhir/Patient
name:
given: John
Multiple sub keys: do not do this with multiple sub keys. This:
name.given: Marie
name.family: Curie
is not the same as:
name:
given: Marie
family: Curie
Creating new profiles
If you want to define your own structures, whether resources or extensions, you define them by writing the intended name followed by their type in square brackets. YamlGen follows the FHIR syntax for defining a type in a choice element. For example, a profile on Patient called nl-core-Patient:
nl-core-Patient[Patient]:
is equivalent to:
StructureDefinition:
id: nl-core-Patient
type: Patient
name: nl-core-Patient
kind: resource
For an extension it is very similar:
preferredPharmacy[Extension]:
is equivalent to:
StructureDefinition:
id: preferredPharmacy
type: Extension
name: preferredPharmacy
kind: complex-type
Using profiles by name: you can use the profiles you defined this way, or any other profile, by using their name, for example nl-core-patient/1:.
Element definitions
Element definitions are one of the most common structures in a FHIR authoring project, and also one of the most verbose. For that reason YamlGen has special syntax: if you start a YAML key with a dot, it defines an element definition, but you write it as if it were a field.
preferredPharmacy[Extension]:
.url:
min: 1
produces:
{
"resourceType": "StructureDefinition",
"id": "preferredPharmacy",
"name": "preferredPharmacy",
"differential": {
"element": [
{
"id": "Extension.url",
"path": "Extension.url",
"min": 1,
}
]
}
}
Paths: you can define full chains of paths by denoting them with a dot. .name.given: produces an element with id and path Patient.name.given.
Slices: you can define slices using a colon. .name:slice1.given produces id Patient.name:slice1.given with path Patient.name.given.
Type slices: you can define type slices using the square-bracket type notation. .birth[Date]: produces id Patient.birth[x] with path Patient.birth and type Date.
Using extensions
You can use any extension by treating it as a regular field in a resource. The following example shows how to create, require and use an extension.
Define an extension:
middlename[Extension]:
url: http://acme.nl/middlename
.value[string]:
max: 1
Define a derived profile of Patient:
dutch-patient[Patient]:
url: http://acme.nl/dutch-patient
.extension:middelname:
max: 1
Create a Patient resource based on the profile and using the extension:
dutch-patient/3:
name:
family: Doe
middlename: van der
Custom accelerators
Sometimes writing each part of a structure on a separate line is more verbose than necessary. YamlGen lets you define a custom accelerator on any FHIR type, which allows inlining those structures. You reference sub nodes using < > angle brackets.
HumanName example:
syntax:
HumanName: <given> | <family>
allows typing name: Adam | Everyman instead of:
name:
given: Adam
family: Everyman
Coding example: you can also use an accelerator to skip defining sub nodes when only one standard node is used:
Coding: <system> | <code>
which allows code: http://somesystem.nl|11331007 instead of:
code:
system: http://somesystem.nl
code: 11331007
Combined with variables this becomes extra powerful: code: $snomed|11331007.
More advanced:
syntax:
cardinality: <min> .. <max>
nl-core-patient[Patient]:
.name:
cardinality: 0 .. *
The syntax definition is currently limited to typename: <reference> or typename: <reference> <literal> <reference>, but is planned to become more flexible.
Nested: you can nest custom accelerators.
syntax:
CodeableConcept: <coding>
Coding: <system> | <code>
Patient/2:
maritalStatus: http://terminology.hl7.org/CodeSystem/v3-MaritalStatus|M
results in:
{
"resourceType": "Patient",
"id": "2",
"maritalStatus": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/v3-MaritalStatus",
"code": "M",
}
]
}
}
You can try this snippet in the YamlGen playground.
Multi-layer: you can even nest three layers deep.
syntax:
CodeableConcept: <coding>
Coding: <_system-code> = <display>
_system-code: <system> | <code>
Patient/2:
maritalStatus: http://terminology.hl7.org/CodeSystem/v3-MaritalStatus|M = Married
Recursive: in the example below the ‘virtual’ field _givens is used as a temporary placeholder to split out several “given” sub fields by referencing itself to parse the remainder.
syntax:
HumanName: <_givens> | <family>
_givens: <given> , <_givens>
Patient/1:
name: Johan Sebastian, Christian | Bach
which results in:
{
"resourceType": "Patient",
"id": "1",
"name": [
{
"given": [
"Johan Sebastian",
"Christian"
],
"family": "Bach"
}
]
}
