Cloud infrastructure
This section describes a sample architecture that can be used as a reference when building a system based on Fire Arrow. The architecture will use Azure components but is not tied to Microsoft Azure.
Sample architecture
The following diagram shows a reference implementation in Azure:

The system consists of the following key components:
- Web application firewall protecting public endpoints
- Authentication layer
- FHIR data layer
- Event processing
- Auxiliary components (container registry and key vault)
Web application firewall
It is good practice to shield your infrastructure with a web application firewall. Cloudflare is used as an example but other products such as Azure Front Door or AWS WAF fulfill the same purpose.
The web application firewall will hide the IP of your API endpoint, provide automated protection against bot attacks and allows you to filter malicious traffic.
Authentication layer
The sole purpose of the authentication layer is to authenticate users and generate corresponding tokens. Fire Arrow uses the token to deduce the client's role and the its FHIR resource id. (see authentication for details) Any cryptographically valid expression that matches the values specified in config.json is accepted, as Fire Arrow only needs to know that the client was authenticated successfully.
The specific access rights of the client are then deduced from content in the FHIR database and the configured access validation rules.
The sample architecture uses Azure B2C as authentication service. A very small service (configured as external API service in Azure B2C) is used to inject the entity type claim into the authentication token. For each configured user flow, the claims service will generate a different entity type claim. (the patient user flow will inject Patient as entity type, the practitioner user flow will inject Practitioner as entity type, and so on)
FHIR data layer
The FHIR data layer is responsible for storing the actual data and is business-case agnostic. It provides the public API for clients to store and retrieve data. This includes binary data, which in the sample architecture is stored on a separate Azure Blob Storage instance.
Event processor
The event processor is business-case specific. It can subscribe to data objects being created or changed in the FHIR data layer and implement custom processors to handle these events. For example, if a patient creates a payout request for an insurance claim, the event processor can inspect the request, validate it and trigger the actual payout.
The separation of business logic from the storage layer and API is an important design concept in Fire Arrow's system architecture to ensure that the core API can be maintained independently, allowing updates and enhancements to Fire Arrow without impacting the overall architecture.
The FHIR database is used as global record and state storage. Clients use the database to download data and make changes. Changes in the FHIR database trigger events, which in turn can activate business logic, again resulting in updated data.
Backend implementations often bundle the API and business logic implementation in a single package. (or several small packages when using microservices) Such a design choice complicates maintenance because the maintenance of the API also impacts the business logic implementation.
Fire Arrow provides a unified API experience to clients and uses event streams as interface to implement custom business logic.
Auxiliary components
The sample architecture uses a container registry as trusted container source for each running application. A key vault is used to manage system-wide secrets.
Azure Identity can be used for inter-service authentication, enabling secure communication between deployed services.
Performance considerations of the Docker container
Fire Arrow's Docker container is built from scratch (meaning, an empty file system) to enable minimum container size and the smallest possible attack surface. Fire Arrow's binary is compiled to native code for fastest code execution.
Fire Arrow is stateless and can scale horizontally if one instance can't fulfill enough simultaneous client requests. (with the exception of automatic entity creation, see authentication)
In general it should be noted that Fire Arrow's performance is largely driven by two things:
- FHIR server performance: FHIR servers are usually slower than SQL databases.
- Validator performance: Very complex validation strategies require multiple requests to the FHIR server until the final data can be returned.
- Cache warm-up: If a Fire Arrow instance sees its first requests from a specific client after some time, Fire Arrow first needs to fetch the corresponding identity resources from the FHIR database. These are cached for subsequent requests, but discarded again when the cache lifetime is exceeded. Warming up the cache makes the first request particularly slow.
Deployment
Fire Arrow should be deployed close to the FHIR server because some validation strategies require multiple requests to the FHIR server. The longer the response time between Fire Arrow and the FHIR server, the longer the overall response time.
Customization of the default Docker container
Fire Arrow is shipped in a default Docker container which contains a sample configuration. The sample configuration points to an invalid FHIR server and an invalid authentication server, so the default container doesn't work out of the box.
The template below can be used to create a custom Docker container with a project-specific config.json:
FROM evoleenpublicacr.azurecr.io/fire_arrow:latest
COPY config.json config.json
# Start server.
EXPOSE 8080
CMD ["/app/bin/fire_arrow"]
Note: Fire Arrow's version should be fixed to a specific release to avoid unintentional upgrades that contain breaking changes.
Values that are stored in config.json don't have to be placed into the container's file system. Any configuration parameter can also be injected as environment variable to avoid having to ship secrets inside the container.
Example:
auth.auto_create_entityinconfig.jsoncan be overridden using the environment variableAUTH_AUTO_CREATE_ENTITYenable_graphql_playgroundcan be overridden using the environment variableENABLE_GRAPHQL_PLAYGROUND
Observability
Fire Arrow logs all messages to standard output by default. These logs can be intercepted and sent to an automated logging system.
When deployed to Azure, Fire Arrow will automatically connect to Azure Application Insights and send request metrics as well as log events to the connected monitoring dashboard. The monitoring dashboard is specified via the environment variable APPLICATIONINSIGHTS_CONNECTION_STRING, which can either be set manually or configured via the Azure Portal.
Tracking Fire Arrow releases
Releases follow semantic versioning conventions.
- Patch releases (1.0.1, 1.0.2) contain bugfixes and changes that are not expected to break anything. Upgrading to higher patch versions within the same minor version should generally be safe.
- Minor releases (1.1.0, 1.2.0) contain feature additions that may have marginal impact on configuration and behavior. It is recommended to read the release notes before upgrading and evaluating how changes impact existing deployments.
- Major releases (1.0.0, 2.0.0) contain major changes that may result in bigger configuration changes to upgrade, include significantly changed behavior or different performance characteristics. It is advised to test these releases before upgrading production systems.
Every release is shipped as a Docker container tagged with the corresponding version number. Release notes list the corresponding changes and, if possible, guidance for upgrades.
Occasionally containers tagged with latest are shipped. These containers contain pre-release features and previews. They shall be considered test builds for evaluation purposes only. Production deployments shall not track the latest tag.