HL7 FHIR Release 3 (STU) introduced the concept of Conditional References in transaction bundles:
When constructing the bundle, the client may not know the logical id of a resource, but it may know identifying information - e.g. an identifier. This situation arises commonly when building transactions from v2 messages. The client could resolve that identifier to a logical id using a search, but that would mean that the resolution to a logical id does not occur within the same transaction as the commit (as well as significantly complicating the client). Because of this, in a transaction (and only in a transaction), references to resources may be replaced by a search URI that describes how to find the correct reference:
<Bundle xmlns="http://hl7.org/fhir">
<id value="20160113160203" />
<type value="transaction" />
<entry>
<fullUrl value="urn:uuid:c72aa430-2ddc-456e-7a09-dea8264671d8" />
<resource>
<Observation>
<subject>
<reference value="Patient?identifier=12345" />
</subject>
<!-- rest of resource omitted -->
</Observation>
</resource>
<request>
<method value="POST" />
</request>
</entry>
</Bundle>
The search URI is relative to the server's [base] path, and always starts with a resource type:
[type]:?parameters....
Only filtering parameters are allowed; none of the parameters that control the return of resources are relevant.When processing transactions, servers SHALL:
... quoted from 2.21.0.17.2 Transaction Processing Rules
I found this concept of conditional references very useful and I would like to use it in my HAPI FHIR client/server app. It seems that it is not supported. Such transaction bundle is refused by server with following error messages:
Client:
HTTP 400 Bad Request: Invalid resource reference found at
path[Observation.subject]
- Does not contain resource type -Patient?identifier=12345
Exception in thread "main" ca.uhn.fhir.rest.server.exceptions.InvalidRequestException: HTTP 400 Bad Request: Invalid resource reference found at path[Observation.subject] - Does not contain resource type - Patient?identifier=12345
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException.newInstance(BaseServerResponseException.java:307)
at ca.uhn.fhir.rest.client.BaseClient.invokeClient(BaseClient.java:290)
at ca.uhn.fhir.rest.client.GenericClient$BaseClientExecutable.invoke(GenericClient.java:637)
at ca.uhn.fhir.rest.client.GenericClient$TransactionExecutable.execute(GenericClient.java:2209)
Server log:
WARN c.u.f.r.s.i.ExceptionHandlingInterceptor [ExceptionHandlingInterceptor.java:135] Failure during REST processing: ca.uhn.fhir.rest.server.exceptions.InvalidRequestException: Invalid resource reference found at
path[Observation.subject]
- Does not contain resource type -Patient?identifier=12345
So my question is:
Is it possible to use conditional references with HAPI FHIR JPA server?
Or if it is not possible, is there work around? Can I use same conditional operation which would resolve the reference or fail if the reference target doesn't exist?
Finally I discovered that it is possible even with HAPI FHIR vesion 2.2
simply by adding following option to the server DaoConfig
:
ca.uhn.fhir.jpa.dao.DaoConfig.setAllowInlineMatchUrlReferences(true)
Should references containing match URLs be resolved and replaced in create and update operations. For example, if this property is set to true and a resource is created containing a reference to
Patient?identifier=12345
, this is reference match URL will be resolved and replaced according to the usual match URL rules.Default is
false
for now, as this is an experimental feature.
See the source code here: github.com/jamesagnew/hapi-fhir