API Design: Compartments

I’ve been reviewing the FHIR (Fast Healthcare Interoperability Resources, http://www.hl7.org/fhir) specification and they have an interesting concept called a compartment.  Per the spec:

Each resource may belong to one or more logical compartments. A compartment is a logical grouping of resources which share a common property. Compartments have two principal roles:

  • Function as an access mechanism for finding a set of related resources quickly
  • Provide a definitional basis for applying access control to resources quickly

Let’s look at these statements one at a time. First, the component concept provides an access mechanism for finding related resources. One very common compartment in the specification is Patient. Other resources, like Condition, clearly have a relationship with Patient. So, if I want to find all conditions that a particular patient has, I actually have two paths for doing this.

  • GET /Patient/[id]/Condition
  • GET /Condition/?patient=[id]

[id] is the unique identifier in question. In this case, both of these requests should return the same thing.  But it’s not quite that simple.  Take another resource, Communication, which deals with secure messages sent as part of patient care.  In this case, we have:

  • GET /Patient/[id]/Communication
  • GET /Communication/?subject=[id]
  • GET /Communication/?sender=[id]
  • GET /Communication/?recipient=[id]

The first example returns any communication that involves the identified patient, whether to, from, or about.  The Communication specific inquiries only allow for inquiry by the attribute of the resource where a Patient identifier can be specified.  It just so happens that in the earlier case, the relationship within Condition is represented in a patient attribute.

Independent of whether you think this is a good or bad thing, this approach where there are two ways of getting to the same resources creates a decision point for the organization.  In a large enterprise, it’s entirely possible that the implementation for different resources may be handled by different teams.  With two (or more) different ways of doing this, it creates the risk of two (or more) different implementations.  It also creates a situation where a resource that can be a compartment needs to make sure that any time a new related resource is defined and implemented, they also need to make a modification to provide the compartment-based inquiry.  Once again, if this is a separate team, this means coordination. Anyone who’s worked in an enterprise knows that the more teams that get involved, the more challenging it becomes.  

These are not insurmountable difficulties by any stretch of the imagination.  In the case of the implementation, the compartment resource should simply act like a façade and make the appropriate calls to the resource (i.e. the implementation of the first URL in the examples above simply turns around and makes the call(s) below them to complete the inquiry, such as Patient calling Condition, or Patient calling Communication).  In the case of the coordination, that’s a matter of education and oversight to make sure it happens.  The greater risk is probably that too many things get defined as a sub-structure within the compartment resource, rather than defined as standalone resources.  This can be avoided by recognizing when a proposed resource has multiple compartments.  Take the following requests:

  • GET /Practitioner/[id]/Condition
  • GET /Condition?asserter=[id]

These inquiry would give me a collection of all conditions that a particular practitioner has ever dealt with.  If Condition  wasn’t a standalone resource, and instead a sub-structure within Patient, how would I go about forming this query?  It can be done, but it’s probably not going to look as simple as what is shown above. This is where I see the hidden strength of this compartment concept.  By recognizing where we can have multiple ways of organizing a particular collection of data and traversing relationships, we can then make good design decisions on what our resources should be.

Finally, FHIR also mentions that the compartment concept can also play a role in access control.  I haven’t dug into this one as much, but I think it may have some potential. The challenge lies with data that really has multiple owners.  As a patient, I may want to use an OAuth model to grant access to my health records to a mobile app I’ve downloaded. My doctor may want to do the same thing for an application he or she uses as part of my care.  The compartment approach could give independent access paths for each of these channels with their own policies.  Again, I need to give this one more thought, but I can definitely understand why HL7 put the bullet point about access control in their specification.

What are your thoughts about this notion of compartments?  Good thing? Bad thing?  Have you implemented a similar approach? What were the pros and cons of it?  Let’s start the discussion.

  

Leave a Reply

Ads

Disclaimer
This blog represents my own personal views, and not those of my employer or any third party. Any use of the material in articles, whitepapers, blogs, etc. must be attributed to me alone without any reference to my employer. Use of my employers name is NOT authorized.