Introduction to the FHIR Server
The following sections describe the basics of FHIR® server technology in InterSystems products. For an overview of what a default FHIR server supports in InterSystems IRIS for Health, seeWhat is Supported?.
In most cases, implementing a FHIR server in Health Connect refers to the ability to accept requests from a FHIR client into an interoperability production. The default FHIR storage architecture provided with the FHIR server in InterSystems IRIS for Health is not available in Health Connect. Though it is possible to write a custom architecture for a FHIR server in Health Connect, most use cases do not include writing this custom code. For more information about using the endpoint of a FHIR server to receive FHIR requests in Health Connect, see FHIR Productions.
Tracing a FHIR request through the FHIR server provides a good overview of the major architectural features of the server. First, the FHIR request must reach the Service, which ensures that the request conforms to the server's FHIR metadata standards and then routes it to the appropriate component to handle the request. The FHIR request can reach this Service in three ways: from a REST handler, through an interoperability production, or from a server-side ObjectScript application. This Service is unrelated to a business service in an interoperability production.
What the Service does with the request depends on the type of request:
If the request contains an HTTP method and endpoint that correspond to a FHIR interactionOpens in a new window, the Service forwards it to the method of the Interactions class that handles that type of FHIR interaction. For example, requests with a read interaction are sent to the Read method of the Interactions class. This Interactions class executes the FHIR interaction, using the InteractionsStrategy class to process the interaction according to the overall purpose of the FHIR server.
For FHIR operationsOpens in a new window, the Service forwards the request to a special class designed to perform operations. InterSystems IRIS for Health applications using the default Resource Repository offer out-of-the-box support for certain FHIR operations.
If the request contains a bundleOpens in a new window of type transaction or batch, the Service forwards the request to a special class that unpacks the bundle to perform the individual HTTP operations.
More About the Service
The Service is a singleton class that allows only one instance of itself to be instantiated for an endpoint. This instantiation occurs when the first FHIR request is sent to the Service by the REST Handler or Business Operation; once instantiated, the Service exists until the process ends. For server applications making FHIR requests programmatically, the app must call HS.FHIRServer.Service.EnsureInstance() to retrieve the Service before sending the first request.
In most cases, the Service class (HS.FHIRServer.Service) is ready to uphold the endpoint's FHIR standard and route requests without being subclassed. Custom logic that determines how the FHIR server behaves is written into the Interactions and InteractionsStrategy subclasses, not the Service.
More About the InteractionsStrategy
The InteractionsStrategy class dictates the overall strategy for the FHIR server. It is the FHIR server application's backend, creating and implementing the environment in which the FHIR data is processed. When the installer creates a new endpoint, it calls the Create method of the InteractionsStrategy to set up the FHIR server for a specific purpose. The InteractionsStrategy superclass is HS.FHIRServer.API.InteractionsStrategy.
In many cases, the InteractionsStrategy is the "storage strategy" for how the FHIR server stores and retrieves FHIR resources. For example, the Resource Repository in InterSystems IRIS for Health is implemented by a subclass of HS.FHIRServer.API.InteractionsStrategy that creates the resource and index tables used to store and retrieve the FHIR data. In applications that are not storing FHIR data, the strategy might set up an environment that communicates with an external FHIR server or any other custom logic that works with the server's FHIR data.
The InteractionsStrategy is also responsible for managing the endpoints that have been registered in the namespace.
More about the Interactions Class
While the InteractionsStrategy class is the backend of the application, it uses the Interactions class to actually execute the FHIR interactions received by the Service. During this process, the Interactions class often calls methods in the InteractionsStrategy class, especially for structures and logic that are common to the entire FHIR server strategy. Because of their interdependent relationship, the Interactions class and InteractionsStrategy class are subclassed together in a unified approach. The Interactions superclass is HS.FHIRServer.API.Interactions.
The methods in the Interactions class that are called by the Service when processing a FHIR request can also be called directly from a server-side ObjectScript application. For example, a server-side application could call the Add method of the Interactions class rather than sending a POST request to the Service. In bypassing the Service, the server application can bypass any restrictions placed on the FHIR server by the Service's metadata. For example, the server application could populate the FHIR server's storage even though the endpoint is read-only for requests going through the Service.
The Interactions class also keeps track of which specialized classes the Service should use to perform FHIR operations, process bundles, and validate FHIR data. The Service obtains the name of these classes from the Interactions object when it needs to take action.
The message class that the server architecture uses to pass FHIR requests is HS.FHIRServer.API.Data.Request.
The message class that the server architecture uses to pass responses from the server to the FHIR client where the request originated is HS.FHIRServer.API.Data.Response.
For information about accessing the FHIR payload in a message, see Accessing FHIR Payloads.
Writing a FHIR Server Application
When developing an application that leverages the FHIR server technology, it is helpful to differentiate between classes that are intended to be subclassed and those that do not need to be modified.
For most applications, the default Service (HS.FHIRServer.Service) effectively enforces the FHIR standard and routes requests for execution, and does not need to be subclassed. Likewise, the classes that process bundles (HS.FHIRServer.DefaultBundleProcessor) and validate resources (HS.FHIRServer.API.ResourceValidator) are fully-functional and do not need to be subclassed, though they can be if custom processing is required. In addition, the ConfigData object (HS.FHIRServer.API.ConfigData) that the Service uses to configure server behavior should not be subclassed.
InterSystems IRIS for Health comes with pre-built Interactions and InteractionsStrategy classes that store and retrieve resources from SQL tables, allowing you to implement a fully-operational FHIR server with minimal custom coding. This storage strategy is known as the Resource Repository.
Developing Custom Functionality
Implementing custom functionality begins with subclassing the Interactions and InteractionsStrategy classes. While its possible to write a completely custom backend for your FHIR server by directly subclassing HS.FHIRServer.API.Interactions and HS.FHIRServer.API.InteractionsStrategy, if your application needs to store and retrieve FHIR resources, it is probably faster and more reliable to subclass the Resource Repository’s HS.FHIRServer.Storage.Json.InteractionsStrategy and HS.FHIRServer.Storage.Json.Interactions classes to implement the custom logic. These classes inherit from the superclasses in the HS.FHIRServer.API package.
After using an IDE to create your Interactions and InteractionsStrategy subclasses, you must modify the following parameters of the InteractionsStrategy subclass:
Modify the StrategyKey parameter to specify a unique identifier.
Modify the InteractionsClass parameter to specify the name of your Interactions subclass.
Once you have successfully subclassed the Interactions and InteractionsStrategy, you can customize other aspects of the server’s functionality like operations, bundle processing, and validation by subclassing the appropriate class (HS.FHIRServer.API.OperationHandler, HS.FHIRServer.DefaultBundleProcessor, and HS.FHIRServer.API.ResourceValidator, respectively). For details about FHIR operations, including adding custom ones without overwriting default operations included with the Resource Repository, see FHIR Operations.
Controlling Server Behavior
The FHIR server installer takes a metadata set and InteractionsStrategy when creating an endpoint. While the InteractionsStrategy provides the backend logic of the FHIR server, the FHIR metadata set controls the capabilities of the server, for example what resources are allowed, what interactions on those resources are allowed, and the valid search parameters. InterSystems provides metadata sets for the base FHIR specifications of the supported FHIR versions; these default metadata sets should NEVER be modified directly. Rather, these standards can be extended or restricted by creating a custom metadata set or, in the special case of the CapabilityStatement, by passing in a modified CapabilityStatement to the SetMetadata method of the Interactions class.
When the installer creates an endpoint, it also creates a ConfigData object (HS.FHIRServer.API.ConfigData) that keeps track of the InteractionsStrategy and metadata of the endpoint and specifies server configuration settings that affect things like security, session timeout, and search results. These configuration settings can be specified with the command-line configuration utility or by programmatically setting properties of the ConfigData object.
The ConfigData object is managed by the InteractionsStrategy and used by the Service to configure itself.
Making REST Calls
When using a REST client to access the InterSystems FHIR server, keep the following in mind:
The base path of an endpoint is: ServerIPAddress:SuperServerPort/baseURL, where:
ServerIPAddress is the IP address of the InterSystems server where the FHIR server is installed.
SuperServerPort is the InterSystems server’s superserver port. You can find this superserver port in the Management Portal by going to System Administration > Configuration > System Configuration > Memory and Startup.
baseURL is the endpoint created during installation. For example, /fhirapp/namespace/fhir/R4.
For example, a REST call to post a resource might look like: