4.4.1Client Configuration

 

This page outlines ways that the client can be configured for specific behaviour.

4.4.2Performance

 

4.4.2.1Server Conformance Check

By default, the client will query the server before the very first operation to download the server's conformance/metadata statement and verify that the server is appropriate for the given client. This check is only done once per server endpoint for a given FhirContext.

This check is useful to prevent bugs or unexpected behaviour when talking to servers. It may introduce unnecessary overhead however in circumstances where the client and server are known to be compatible. The following example shows how to disable this check.

// Create a context
FhirContext ctx = FhirContext.forDstu2();

// Disable server validation (don't pull the server's metadata first)
ctx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);

// Now create a client and use it
String serverBase = "http://fhirtest.uhn.ca/baseDstu2";
IGenericClient client = ctx.newRestfulGenericClient(serverBase);

4.4.2.2Deferred Model Scanning

By default, HAPI will scan each model type it encounters as soon as it encounters it. This scan includes a check for all fields within the type, and makes use of reflection to do this.

While this process is not particularly significant on reasonably performant machines (one benchmark showed that this takes roughly 0.6 seconds to scan all types on one developer workstation), on some devices (e.g. Android phones where every millisecond counts) it may be desirable to defer this scan.

When the scan is deferred, objects will only be scanned when they are actually accessed, meaning that only types that are actually used in an application get scanned.

The following example shows how to defer model scanning:

// Create a context and configure it for deferred child scanning
FhirContext ctx = FhirContext.forDstu2();
ctx.setPerformanceOptions(PerformanceOptionsEnum.DEFERRED_MODEL_SCANNING);

// Now create a client and use it
String serverBase = "http://fhirtest.uhn.ca/baseDstu2";
IGenericClient client = ctx.newRestfulGenericClient(serverBase);

4.4.3Configuring the HTTP Client

 

REST clients (both Generic and Annotation-Driven) use Apache HTTP Client as a provider by default (except on Android, where OkHttp is the default).

The Apache HTTP Client is very powerful and extremely flexible, but can be confusing at first to configure, because of the low-level approach that the library uses.

In many cases, the default configuration should suffice. HAPI FHIR also encapsulates some of the more common configuration settings you might want to use (socket timeouts, proxy settings, etc.) so that these can be configured through HAPI's API without needing to understand the underlying HTTP Client library.

This configuration is provided by accessing the IRestfulClientFactory class from the FhirContext.

Note that individual requests and responses can be tweaked using Client Interceptors. This approach is generally useful for configuration involving tweaking the HTTP request/response, such as adding authorization headers or logging.

4.4.3.1Setting Socket Timeouts

The following example shows how to configure low level socket timeouts for client operations.

FhirContext ctx = FhirContext.forR4();

// Set how long to try and establish the initial TCP connection (in ms)
ctx.getRestfulClientFactory().setConnectTimeout(20 * 1000);

// Set how long to block for individual read/write operations (in ms)
ctx.getRestfulClientFactory().setSocketTimeout(20 * 1000);

// Create the client
IGenericClient genericClient = ctx.newRestfulGenericClient("http://localhost:9999/fhir");

4.4.3.2Configuring an HTTP Proxy

The following example shows how to configure the use of an HTTP proxy in the client.

FhirContext ctx = FhirContext.forR4();

// Set connections to access the network via the HTTP proxy at
// example.com : 8888
ctx.getRestfulClientFactory().setProxy("example.com", 8888);

// If the proxy requires authentication, use the following as well
ctx.getRestfulClientFactory().setProxyCredentials("theUsername", "thePassword");

// Create the client
IGenericClient genericClient = ctx.newRestfulGenericClient("http://localhost:9999/fhir");

4.4.3.3Using OkHttp instead of Apache HttpClient

As of HAPI FHIR 2.0, an alternate client implementation is available. This client replaces the low-level Apache HttpClient implementation with the Square OkHttp library.

Changing HTTP implementations should be mostly transparent (it has no effect on the actual FHIR semantics which are transmitted over the wire) but might be useful if you have an application that uses OkHttp in other parts of the application and has specific configuration for that library.

Note that as of HAPI FHIR 2.1, OkHttp is the default provider on Android, and will be used without any configuration being required. This is done because HttpClient is deprecated on Android and has caused problems in the past.

To use OkHttp, first add the library as a dependency to your project POM:

<dependency>
    <groupId>ca.uhn.hapi.fhir</groupId>
    <artifactId>hapi-fhir-client-okhttp</artifactId>
    <version>${hapi_stable_version}</version>		
</dependency>

Then, set the client factory to use OkHttp.

FhirContext ctx = FhirContext.forDstu3();

// Use OkHttp
ctx.setRestfulClientFactory(new OkHttpRestfulClientFactory(ctx));

// Create the client
IGenericClient genericClient = ctx.newRestfulGenericClient("http://localhost:9999/fhir");