FHIR API
Blaze exposes a FHIR RESTful API under the default context path of /fhir
. The CapabilityStatement exposed under /fhir/metadata
can be used to discover the capabilities of Blaze. Everything stated there can be considered to be implemented correctly. If you find any discrepancies, please open an issue.
Interactions
Instance Level
- Read
- Versioned Read
- Update
- Delete
- Delete History Since 0.30.1
- History
Type Level
System Level
Operations
The following Operations are implemented:
- $compact Since 0.31
- $graphql
- Measure $evaluate-measure
- Patient $everything Since 0.22
- Patient $purge Since 0.30.1
- CodeSystem $validate-code Since 0.32
- ValueSet $expand Since 0.32
- ValueSet $validate-code Since 0.32
Asynchronous Requests
Some requests like $evaluate-measure or complex FHIR searches with _summary=count
can take longer as a typical HTTP request response cycle should be open. Typical HTTP request timeouts from client and intermediates are 30 seconds. Requests that take longer than that would require special handling. In oder to overcome that synchronous request handling, FHIR specifies Asynchronous Request Patterns.
Blaze implements the Asynchronous Interaction Request Pattern from FHIR R5.
Example FHIR Search Request
To initiate a sync request, the HTTP header Prefer
has to set to respond-async
:
curl -svH 'Prefer: respond-async' "http://localhost:8080/fhir/Observation?code=http://loinc.org|8310-5&_summary=count"
The response will look like this:
HTTP/1.1 202 Accepted
Content-Location: http://localhost:8080/fhir/__async-status/DD7MLX6H7OGJN7SD
The status code 202 indicates that the request was accepted and will continue to be processed in the background. The Content-Location
header contains an opaque URL to a status endpoint.
NOTE
Please be aware that Blaze will respond synchronously if the response is available in time or the async handling isn't implemented yet. Clients always have to be able to handle synchronous responses as well.
Polling that status endpoint:
curl -svH 'Accept: application/fhir+json' "http://localhost:8080/fhir/__async-status/DD7MLX6H7OGJN7SD"
will either result in a intermediate result like this:
HTTP/1.1 202 Accepted
X-Progress: in-progress
or in the final response:
HTTP/1.1 200 OK
Content-Type: application/fhir+json;charset=utf-8
Content-Length: 412
The response itself will be a Bundle of type batch-response
:
{
"resourceType": "Bundle",
"id": "DD7MLX6JYN54OHKZ",
"type": "batch-response",
"entry": [
{
"response": {
"status": "200"
},
"resource": {
"resourceType": "Bundle",
"id": "DD7MLX6JZHGD5YSA",
"type": "searchset",
"total": 1689,
"link": [
{
"relation": "self",
"url": "http://localhost:8080/fhir/Observation?code=http%3A%2F%2Floinc.org%7C8310-5&_summary=count&_count=50"
}
]
}
}
]
}
Cancelling an Async Request
Async requests can be cancelled before they are completed:
curl -svXDELETE "http://localhost:8080/fhir/__async-status/DD7MLX6H7OGJN7SD"
Paging Sessions
Interactions and operations that return a large list of resources support paging via Bundle resources. The various Bundle resources are interlinked via the next link. The process of retrieving a part of or all Bundle resources (pages) of a large response forms a paging session. Paging sessions have the following properties:
Stable
Paging sessions operate on a stable database snapshot. Next links will point to custom paging session endpoints. The endpoints will expire after for 4 hours in order to constrain the usage of a paging session. That also means that clients which have access to a paging session, will be able to access deleted and changed resources for up to 4 hours.
Expire
Paging sessions will expire after 4 hours without activity. Activities are requesting the first or next page.
Fast
Paging sessions don't require initial setup time and show constant costs per page in most cases. In fact paging sessions don't require book keeping at server side at all. Their state is solely communicated via link URLs. For search requests with more than one parameter, page costs can vary because of internal query handling.
Encrypted
The variable part of paging URLs is encrypted to ensure confidentiality and integrity of the paging parameters. Confidentiality is important in case some of the original query parameters contain sensitive information. To mitigate the risk of exposing this data, FHIR searches are often executed via POST requests, which helps prevent sensitive information from being logged in URLs. Consequently, it is essential that paging URLs do not reveal any confidential data. Integrity is important, because it should not be possible to manipulate the paging URL in order to access a different paging session.
Encryption Key Management
- Key Rotation
- Encryption keys are rotated every two hours. Each key is valid for a maximum of four hours, with a total of three keys stored at any time.
- Storage
- Currently, encryption keys are stored in plain text within the admin database. While these keys are not accessible via an API, they are also not encrypted with an external key encryption method.
- Future Improvements
- Implementing external key encryption is feasible but would require additional infrastructure. If you believe that key encryption is necessary, please open an issue for further discussion.
Absolute URLs
Blaze has to generate absolute URLs of its own in links and Location headers. By default Blaze assumes to be accessible under http://localhost:8080
. The environment variable BASE_URL
can be used to change this.
Besides the static BASE_URL
setting, Blaze also respects the reverse proxy headers X-Forwarded-Host, X-Forwarded-Proto and Forwarded to generate its base URL dynamically.