On this page:

9.4FHIR Gateway Examples

 

This page contains example interceptors that can be registered with the FHIR Gateway module.

9.4.1Example: Direct Search based on Parameter Value

 

The following example shows an interceptor that looks for a search parameter for gateway searches and directs them to the appropriate target based on the parameter value. This could be used in cases where the same type of resource is served by multiple targets but additional logic is needed in order to determine which target to actually query.

/**
 * This interceptor expects Observation searches to contain a mandatory
 * parameter called <code>Category</code>. This parameter may have the
 * values <code>lab</code> or <code>vitals</code> and will direct the
 * search to one target or the other.
 */
@Interceptor
public class ChooseGatewaySearchTargetBasedOnParameterInterceptor {

	@CdrHook(CdrPointcut.FHIRGW_SEARCH_TARGET_PREINVOKE)
	public void hook(SearchRequest theRequest, GatewayTargetJson theTarget) {

		// This interceptor only applies to Observation searches
		if (!theRequest.getResourceType().equals("Observation")) {
			return;
		}

		// Look for a parameter on the search request called: category
		String category = theRequest.getParameter("category");

		// Remove the parameter from the request so that we don't pass
		// it to the target servers
		theRequest.removeParameters("category");

		// Depending on the value, only query specific targets
		if ("lab".equals(category)) {
			if (!theTarget.getId().equals("lab_target")) {
				theRequest.setSkip(true);
			}
			return;
		}
		if ("vitals".equals(category)) {
			if (!theTarget.getId().equals("vital_target")) {
				theRequest.setSkip(true);
			}
			return;
		}

		// If the category parameter value was missing or invalid, default to
		// an HTTP 400 Invalid Request response from the gateway
		throw new InvalidRequestException("Missing or invalid required parameter: category");
	}

}

Using this interceptor, the following search URL would be directed only to the Gateway target server with the ID lab_target.

http://fhir.example.com/Observation?category=lab

9.4.2Example: Modify Target Search based on Previous Target Search

 

This example shows how to modify a search being performed on multiple targets so that the actual query used for the later targets is changed based on the results from the search on the earlier targets.

/**
 * This interceptor is intended to be used in a FHIR Gateway that is configured with multiple
 * search targets. It uses the results of the first target's search results to inform what the
 * query should look like for the second target.
 *
 * While the exact pattern being used here is obviously a bit contrived, it is a simple
 * demonstration of a pattern that can be useful when you have complicated gateway setups.
 *
 * This interceptor would only be effective if the Gateway Route is configered in non-parallel
 * mode, since the results from the first target will not always be available when the second
 * target is being invoked if the searches are performed in parallel.
 */
@Interceptor
public class GatewayEnrichSearchUsingPreviousTargetResults {

	@CdrHook(CdrPointcut.FHIRGW_SEARCH_TARGET_PREINVOKE)
	public void hook(SearchRequest theRequest, GatewayTargetJson theTarget, SearchResultsAccumulator theSearchResultsAccumulator) {

		// We assume there are two targets, one called "target1" and one called "target2". This
		// logic only applies to the second target.
		if (!theTarget.getId().equals("target2")) {
			return;
		}

		/*
		 * For this example, we look for the first patient in the search results, and
		 * then modify the query for the second target based on those results. This
		 * is just an example of the type of logic you might use.
		 */
		List<IBaseResource> target1Results = theSearchResultsAccumulator.getResults("target1");
		Optional<Patient> patient = target1Results
			.stream()
			.filter(t <i class="fas fa-angle-double-right"></i> t instanceof Patient)
			.map(t <i class="fas fa-angle-double-right"></i> (Patient) t)
			.findFirst();

		if (!patient.isPresent()) {
			return;
		}

		// Add a search parameter to the second target search request
		String searchForId = patient.get().getId().replaceAll("^1", "2");
		theRequest.addParameter("_id", searchForId);
	}

}