Status: Draft
This repository contains the Clojure library to generate the Type Schema, an intermediate representation for FHIR SDK generation.
Recommended file extension for the FHIR Type Schema is .ts.json.
Table of Contents
Long story short:
- Custom FHIR SDK is better than a universal one
- Type Schema makes it simple.
For the long story, take a look at: Type Schema: a Pragmatic Approach to Build FHIR SDK
The Type Schema is a JSON-based format that provides a simplified representation of FHIR entities (resources, primitive types, etc.).
JSON Schema to validate the FHIR Type Schemas is placed in <docs/type-schema.schema.json>.
Examples of Type Schema and related FHIR Schema are placed in <docs/examples>.
All FHIR Type Schema entities share a common structure with an identifier field which is an ID if defined in the root, or reference if used in other ways:
kind: The type of entity, which can be:"primitive-type": Primitive types like string, boolean, decimal"resource": FHIR resources like Patient, Observation"complex-type": Complex data types like HumanName, Address"nested": Backbone elements within resources
package: The FHIR package source (e.g., "hl7.fhir.r4.core")version: The version of the FHIR package (e.g., "4.0.1")name: The name of the type (e.g., "Patient", "string")url: The canonical URL of the type (e.g., "http://hl7.org/fhir/StructureDefinition/Patient")
Other fields are specific to the kind.
Primitive types are simpler with:
identifier: As described abovedescription: Human-readable description of the entitybase: Reference to the base type in accordance to Structure Definitiondependencies: References to all mentioned FHIR entities
Resources and complex types include:
identifier: As described abovedescription: Human-readable description of the entitybase: Reference to the base type in accordance to Structure Definitionfields: Object mapping field names to their definitions, including:type: Reference to another typereference: Reference to another typearray: Boolean indicating if the field can have multiple valuesrequired: Boolean indicating if the field is requiredenum: List of possible values for the primitive type if we can simply expand value set for itchoices: For choice[x] elements, lists possible type optionschoiceOf: Name of the choice type
nested: Array of nested backbone element type definitionsdependencies: References to all mentioned FHIR entities
For details on special cases like choice types, see ./docs.
Backbone elements are represented as:
identifier: As described above with kind="nested"base: Reference to the base type in accordance to Structure Definition. Usually references BackboneElement typefields: Object mapping field names to their definitions, see abovedependencies: References to all mentioned FHIR entities
This normalized structure eliminates the complexity of navigating differential and snapshot views in Structure Definitions, making it straightforward to generate strongly-typed code in any programming language.
You can see the full type-schema structure in ./test/golden/patient/patient.ts.json, which demonstrates how a Patient resource is represented in our normalized format.
This structure makes it easy to understand the relationships between FHIR resources and their properties during generation process without having to parse and lookup for the more complex original FHIR definitions.
{
"identifier" : {
"kind" : "resource",
"package" : "hl7.fhir.core.r4",
"version" : "4.0.1",
"name" : "Patient",
"url" : "http://hl7.org/fhir/StructureDefinition/Patient"
},
"base" : {
"kind" : "resource",
"package" : "hl7.fhir.r4.core",
"version" : "4.0.1",
"name" : "DomainResource",
"url" : "http://hl7.org/fhir/StructureDefinition/DomainResource"
},
"description" : "Demographics and other administrative information about an individual or animal receiving care or other health-related services.",
"fields" : {
"address" : {
"array" : true,
"required" : false,
"excluded" : false,
"type" : {
"kind" : "complex-type",
"package" : "hl7.fhir.r4.core",
"version" : "4.0.1",
"name" : "Address",
"url" : "http://hl7.org/fhir/StructureDefinition/Address"
}
},
"managingOrganization" : {
"array" : false,
"required" : false,
"excluded" : false,
"type" : {
"kind" : "complex-type",
"package" : "hl7.fhir.r4.core",
"version" : "4.0.1",
"name" : "Reference",
"url" : "http://hl7.org/fhir/StructureDefinition/Reference"
},
"reference" : [ {
"kind" : "resource",
"package" : "hl7.fhir.r4.core",
"version" : "4.0.1",
"name" : "Organization",
"url" : "http://hl7.org/fhir/StructureDefinition/Organization"
} ]
},
...
},
"nested": [...],
"dependencies" : [ {
"kind" : "resource",
"package" : "hl7.fhir.r4.core",
"version" : "4.0.1",
"name" : "DomainResource",
"url" : "http://hl7.org/fhir/StructureDefinition/DomainResource"
},
...
]
}JSON Schema for the FHIR Type Schema is placed in <docs/type-schema.schema.json>.
How to check JSON by this schema:
$ npm install -g ajv-cli
$ ajv test -s docs/type-schema.schema.json -d docs/example.ts.json --valid
$ find . -name "*.ts.json" | xargs -n 1 ajv test -s docs/type-schema.schema.json --valid -dThe typical SDK generation pipeline with Type Schema consists of several transformation steps:
-
FHIR Package Loader Github → Start with a FHIR package (e.g.,
hl7.fhir.r4.core@4.0.1)- Contains Structure Definitions, Value Sets, and other FHIR artifacts and Aidbox configuration packages with Custom Resource, Acess Policy, User etc.
- Provides the canonical definitions for FHIR resources and types
-
FHIR Artifact Regestry : TBD
-
FHIR Schema Generation Github
- Transform Structure Definitions into FHIR Schema
- Simplifies the complex differential/snapshot structure
- Normalizes resource and type definitions
- Recommended extension:
.fs.json
-
Type Schema Generation Github
- Transform FHIR Schema into Type Schema
- Further simplifies and normalizes for code generation
- Makes the structure more language-agnostic
- Recommended extension:
.ts.json
-
SDK Generation (language-specific part)
- Consume Type Schema to generate language-specific code
- Generate classes, types, or structs for each resource
- Add validation, serialization, and deserialization capabilities
- Implement FHIR operations as language-specific methods
- Output is ready-to-use SDK code in target language
See the example of the last step implemented in TypeScript for several languages here: fhir-schema-codegen
This pipeline separates concerns between parsing FHIR packages, transforming into intermediate representations, and generating language-specific code, making each step more maintainable and reusable.
- ndjson/path output from CLI
- Bindings
- Extension
- Docstrings
- Profiles
- Search Parameters
- Operations
You can download the latest release jar from the GitHub Releases page. Or native standalone binaries that don't require a Java runtime. Simply download the appropriate binary for your operating system and architecture.
$ ./type-schema --help
Type Schema Generator for FHIR packages
Usage: type-schema [options] [<package-name>]
Options:
-o, --output DIR Output directory or .ndjson file
--separated-files Output each type schema to a separate file (requires -o to be set to a directory)
--treeshake TYPES List of required types to include in output (comma-separated); output will only include these types and their dependencies
--drop-cache Drop all package caches
-v, --verbose Enable verbose output
--version Print version information and exit
-h, --help Show this help message
Examples:
type-schema hl7.fhir.r4.core@4.0.1 # Output to stdout
type-schema -v hl7.fhir.r4.core@4.0.1 # Verbose mode
type-schema -o output hl7.fhir.r4.core@4.0.1 # Output to directory
type-schema -o result.ndjson hl7.fhir.r4.core@4.0.1 # Output to file
type-schema -o output --separated-files hl7.fhir.r4.core@4.0.1 # Output each type schema to a separate file
type-schema --treeshake Patient,Observation hl7.fhir.r4.core@4.0.1 # Only include specified types and dependencies
type-schema --drop-cache # Drop all package caches
type-schema --version # Show version$ clj -M -m main --version
type-schema version 0.0.8$ make build
target/type-schema.jar
$ java -jar target/type-schema.jar --version
type-schema version 0.0.8$ ./type-schema --version
type-schema version 0.0.8-
Generate Type Schemas for hl7.fhir.r4.core to ndjson file:
$ clj -M -m main hl7.fhir.r4.core@4.0.1 -o ./fhir.r4.ndjson -
Generate Type Schemas for Patient resource from hl7.fhir.r4.core and its dependencies:
$ clj -M -m main hl7.fhir.r4.core@4.0.1 --treeshake Patient -o output --separated-files
