|
|
|
|
@ -7,13 +7,44 @@ healthcare-related information. The base building block of FHIR are so-called *r
|
|
|
|
|
have a type that defines their base schema. This schema can be further customised through one or
|
|
|
|
|
more *profiles*.
|
|
|
|
|
|
|
|
|
|
As an example, [`Questionnaire`] is the resource type for medical forms that can be used for various
|
|
|
|
|
purposes. This type defines several fields such as an *optional* `title` property containing a human
|
|
|
|
|
friendly name for the form. [`ISiKFormularDefinition`], in turn, is a profile on `Questionnaire`
|
|
|
|
|
created by Germany's national health agency, gematik, for use within hospitals. It customises the
|
|
|
|
|
schema of `Questionnaire` in several ways, such as making `title` required rather than optional.
|
|
|
|
|
As an example, [`Questionnaire`] is the resource type for generic medical forms. This type defines
|
|
|
|
|
several fields such as an *optional* `title` property containing a human readable name for the form.
|
|
|
|
|
[`ISiKFormularDefinition`], in turn, is a profile on `Questionnaire` created by Germany's national
|
|
|
|
|
health agency, gematik, for use within hospitals. It customises the schema of `Questionnaire` in
|
|
|
|
|
several ways, such as making `title` required rather than optional.
|
|
|
|
|
|
|
|
|
|
Both resource types and profiles can be uniquely identified by their [canonical URL].
|
|
|
|
|
Profiles can extend either resource types or other profiles, meaning it is possible to build chains
|
|
|
|
|
of profiles. Both resource types and profiles are described via [`StructureDefinition`]s which are
|
|
|
|
|
uniquely identified by their [canonical URL].
|
|
|
|
|
|
|
|
|
|
``` json5
|
|
|
|
|
{
|
|
|
|
|
// This is the profile ISiKFormularDefinition v5.0.0, created by gematik GmbH
|
|
|
|
|
"resourceType": "StructureDefinition",
|
|
|
|
|
"id": "ISiKFormularDefinition",
|
|
|
|
|
"url": "https://gematik.de/fhir/isik/StructureDefinition/ISiKFormularDefinition",
|
|
|
|
|
"version": "5.0.0",
|
|
|
|
|
"publisher": "gematik GmbH",
|
|
|
|
|
// It extends the base type Questionnaire from FHIR v4.0.1
|
|
|
|
|
"type": "Questionnaire",
|
|
|
|
|
"fhirVersion": "4.0.1",
|
|
|
|
|
// It is based directly on the base type without intermediary profiles
|
|
|
|
|
"baseDefinition": "http://hl7.org/fhir/StructureDefinition/Questionnaire",
|
|
|
|
|
// It changes the base type, among others, by making the title field mandatory
|
|
|
|
|
"differential": {
|
|
|
|
|
"element": [{
|
|
|
|
|
"id": "Questionnaire.title",
|
|
|
|
|
"min": 1,
|
|
|
|
|
"mustSupport": true,
|
|
|
|
|
...
|
|
|
|
|
}, ...]},
|
|
|
|
|
...
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
While the above example is trivial, the customisations achievable via profiling can be extensive. As
|
|
|
|
|
a result, it is crucial for implementations to understand what profiles are being used when
|
|
|
|
|
exchanging data.
|
|
|
|
|
|
|
|
|
|
## The problems of using FHIR resources in Matrix
|
|
|
|
|
|
|
|
|
|
@ -27,24 +58,31 @@ render the resource as an interactive form for the user to fill out and send bac
|
|
|
|
|
|
|
|
|
|
Similarly, clients that connect external systems to Matrix may want to automatically process certain
|
|
|
|
|
resources. For instance, an anamnesis bot may want to export received `QuestionnaireResponse`s into
|
|
|
|
|
a surgery's patient management system. Again, the generic MIME type forces such a client to download
|
|
|
|
|
the file to determine if it is indeed a `QuestionnaireResponse`.
|
|
|
|
|
a hospital's patient management system. Again, the generic MIME type forces such a client to
|
|
|
|
|
download the file to determine if it is indeed a `QuestionnaireResponse`.
|
|
|
|
|
|
|
|
|
|
These problems would be obliterated if FHIR resources were inlined into Matrix events. However, this
|
|
|
|
|
isn't always possible due to the [64 KiB event size limit]. Additionally, no suitable event type or
|
|
|
|
|
content block exists, as of writing.
|
|
|
|
|
These problems would be mitigated to some extent if FHIR resources were inlined into Matrix events.
|
|
|
|
|
However, serialized resources contain only limited information about the underlying
|
|
|
|
|
`StructureDefinition`. Most importantly the base resource type is missing, making it difficult for
|
|
|
|
|
implementations that support a base type but not a specific profile to fall back in a reasonable
|
|
|
|
|
way. Furthermore, inlining isn't always possible due to the [64 KiB event size limit] and no
|
|
|
|
|
suitable event type or content block exists, as of writing.
|
|
|
|
|
|
|
|
|
|
## Proposal
|
|
|
|
|
|
|
|
|
|
To enable the efficient exchange of FHIR resources in either inline or file form, a new event type
|
|
|
|
|
`m.fhir.resource` is introduced. This type mandates the following properties in `content`:
|
|
|
|
|
|
|
|
|
|
- `canonical_url` (string, required): The resource's [canonical URL], that is the globally unique
|
|
|
|
|
identifier defining its base schema. MAY contain a version suffix separated by `|` as per the FHIR
|
|
|
|
|
specification.
|
|
|
|
|
- `profiles`: (array of strings): The canonical URLs of the profiles the resource conforms to (if
|
|
|
|
|
any). The order of elements in the array is arbitrary, similar to FHIR's own [`Meta.profile`]
|
|
|
|
|
property.
|
|
|
|
|
To enable the compatible and efficient exchange of FHIR resources in either inline or file form, a
|
|
|
|
|
new event type `m.fhir` is introduced. This type mandates the following properties in `content`:
|
|
|
|
|
|
|
|
|
|
- `m.fhir.structure_definition` (object, required): Information about the resource's
|
|
|
|
|
`StructureDefinition`.
|
|
|
|
|
- `url` (string, required): The [canonical URL] of the most specific `StructureDefinition`
|
|
|
|
|
describing the resource. This is equivalent to [`StructureDefinition.url`].
|
|
|
|
|
- `version` (string, required): The version of the `StructureDefinition`. This is equivalent to
|
|
|
|
|
[`StructureDefinition.version`].
|
|
|
|
|
- `type` (string, required): The `StructureDefinition`'s base type. This is equivalent to
|
|
|
|
|
[`StructureDefinition.type`].
|
|
|
|
|
- `fhir_version` (string, required): The version of the FHIR specification on which the
|
|
|
|
|
`StructureDefinition` is based. This is equivalent to [`StructureDefinition.fhirVersion`].
|
|
|
|
|
- `m.fhir.resource` (object, required if `m.file` is missing): The serialised JSON if it fits within
|
|
|
|
|
the [64 KiB event size limit].
|
|
|
|
|
- `m.file` (object, required if `m.fhir.resource` is missing): An [MSC3551] content block describing
|
|
|
|
|
@ -52,13 +90,15 @@ To enable the efficient exchange of FHIR resources in either inline or file form
|
|
|
|
|
|
|
|
|
|
``` json5
|
|
|
|
|
{
|
|
|
|
|
"type": "m.fhir.resource",
|
|
|
|
|
"type": "m.fhir",
|
|
|
|
|
"content": {
|
|
|
|
|
// Metadata to help identify the resource
|
|
|
|
|
"canonical_url": "http://hl7.org/fhir/StructureDefinition/Questionnaire|4.0.1",
|
|
|
|
|
"profiles": [
|
|
|
|
|
"https://gematik.de/fhir/isik/StructureDefinition/ISiKFormularDefinition|5.0.0"
|
|
|
|
|
],
|
|
|
|
|
"m.fhir.structure_definition": {
|
|
|
|
|
"url": "https://gematik.de/fhir/isik/StructureDefinition/ISiKFormularDefinition",
|
|
|
|
|
"version": "5.0.0",
|
|
|
|
|
"type": "Questionnaire",
|
|
|
|
|
"fhir_version": "4.0.1",
|
|
|
|
|
},
|
|
|
|
|
// Either: The resource in inline form
|
|
|
|
|
"m.fhir.resource": {
|
|
|
|
|
"resourceType": "Questionnaire",
|
|
|
|
|
@ -74,36 +114,44 @@ To enable the efficient exchange of FHIR resources in either inline or file form
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
The `url` and `version` properties, on the one hand, allow implementations with support for the
|
|
|
|
|
particular profile to activate dedicated display or processing logic. The `type` and `fhir_version`
|
|
|
|
|
properties, on the other hand, enable implementations *without* support for the specific profile to
|
|
|
|
|
offer fallback behaviour if they have generic support for the resource's base type.
|
|
|
|
|
|
|
|
|
|
## Potential issues
|
|
|
|
|
|
|
|
|
|
FHIR includes generic resources such as [`Bundle`] which wrap other resources. The `canonical_url`
|
|
|
|
|
will not help clients understand the wrapped content without downloading it in these cases.
|
|
|
|
|
Dedicated event types may be introduced in future to cater to these situations.
|
|
|
|
|
FHIR includes generic resources such as [`Bundle`] which wrap other resources. The metadata in
|
|
|
|
|
`m.fhir.structure_definition` will not help clients understand the wrapped content without
|
|
|
|
|
downloading it in these cases. Dedicated event types or further metadata fields may be introduced in
|
|
|
|
|
future to cater to these situations.
|
|
|
|
|
|
|
|
|
|
## Alternatives
|
|
|
|
|
|
|
|
|
|
Dedicated MIME types per resource, version and serialisation format could be introduced. Since FHIR
|
|
|
|
|
supports a vast number of resources this doesn't appear practical, however.
|
|
|
|
|
supports a vast number of resources and profiles this doesn't appear practical, however.
|
|
|
|
|
|
|
|
|
|
[RFC 2045] allows MIME types to include modifying parameters. The canonical URL could, therefore, be
|
|
|
|
|
included alongside the media type[^1].
|
|
|
|
|
[RFC 2045] allows MIME types to include modifying parameters. The contents of
|
|
|
|
|
`m.fhir.structure_definition` could, therefore, be included alongside the media type[^1].
|
|
|
|
|
|
|
|
|
|
Content-type: application/fhir+json; canonical_url="http://hl7.org/fhir/patient.html|4.0.1"
|
|
|
|
|
``` http
|
|
|
|
|
Content-type: application/fhir+json; url="https://gematik.de/fhir/isik/StructureDefinition/ISiKFormularDefinition"; ...
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
This would allow reusing the `m.file` message type but leaks the resource type to the home server in
|
|
|
|
|
This would allow reusing the `m.file` message type but leaks metadata to the home server in
|
|
|
|
|
[`POST /_matrix/media/v3/upload`].
|
|
|
|
|
|
|
|
|
|
## Security considerations
|
|
|
|
|
|
|
|
|
|
Malicious clients could attempt to trick other clients into automatically downloading files by
|
|
|
|
|
faking the metadata in `m.fhir.resource` events. As a minimal defense, clients SHOULD sanity-check
|
|
|
|
|
the size of the downloaded file by issuing a HEAD request and refuse to download large files without
|
|
|
|
|
explicit user consent.
|
|
|
|
|
faking the metadata in `m.fhir.structure_definition`. As a minimal defense, clients SHOULD
|
|
|
|
|
sanity-check the size of the downloaded file by issuing a HEAD request and refuse to automatically
|
|
|
|
|
download large files without explicit user consent.
|
|
|
|
|
|
|
|
|
|
## Unstable prefix
|
|
|
|
|
|
|
|
|
|
While this MSC is not considered stable, the event type `m.fhir.resource` should be referred to as
|
|
|
|
|
`de.gematik.msc4302.fhir.resource`.
|
|
|
|
|
While this MSC is not considered stable, the event type `m.fhir` should be referred to as
|
|
|
|
|
`de.gematik.msc4302.fhir`.
|
|
|
|
|
|
|
|
|
|
## Dependencies
|
|
|
|
|
|
|
|
|
|
@ -116,11 +164,15 @@ None.
|
|
|
|
|
[FHIR]: https://hl7.org/fhir/
|
|
|
|
|
[`Questionnaire`]: http://hl7.org/fhir/StructureDefinition/Questionnaire
|
|
|
|
|
[`ISiKFormularDefinition`]: https://gematik.de/fhir/isik/StructureDefinition/ISiKFormularDefinition
|
|
|
|
|
[`StructureDefinition`]: https://build.fhir.org/structuredefinition.html
|
|
|
|
|
[canonical URL]: https://build.fhir.org/references.html#canonical
|
|
|
|
|
[`m.file`]: https://spec.matrix.org/v1.14/client-server-api/#mfile
|
|
|
|
|
[`QuestionnaireResponse`]: http://hl7.org/fhir/StructureDefinition/QuestionnaireResponse
|
|
|
|
|
[64 KiB event size limit]: https://spec.matrix.org/v1.16/client-server-api/#size-limits
|
|
|
|
|
[`Meta.profile`]: http://hl7.org/fhir/resource-definitions.html#Meta.profile
|
|
|
|
|
[`StructureDefinition.url`]: https://build.fhir.org/structuredefinition-definitions.html#StructureDefinition.url
|
|
|
|
|
[`StructureDefinition.version`]: https://build.fhir.org/structuredefinition-definitions.html#StructureDefinition.version
|
|
|
|
|
[`StructureDefinition.type`]: https://build.fhir.org/structuredefinition-definitions.html#StructureDefinition.type
|
|
|
|
|
[`StructureDefinition.fhirVersion`]: https://build.fhir.org/structuredefinition-definitions.html#StructureDefinition.fhirVersion
|
|
|
|
|
[MSC3551]: https://github.com/matrix-org/matrix-spec-proposals/pull/3551
|
|
|
|
|
[`Bundle`]: http://hl7.org/fhir/StructureDefinition/Bundle
|
|
|
|
|
[RFC 2045]: https://datatracker.ietf.org/doc/html/rfc2045#section-5
|
|
|
|
|
|