Survey – Proposed API change to make related items easier to work with…

If you’ve been working with related items, you may have found that it’s a bit inconvenient to use right now. Specifically:

  • To set up a two-way-link between objects, you need to insert one, insert the second with related items, and then update the first one with a related item link.

  • You have to physically set up the links for every object (ie add a HealthRecordItemRelationship to CommonData.RelatedItems) – there’s no helper to do it, and it’s hard for us to write one.

  • You have to fetch each related item separately

We’re having some discussions around how to fix the first one, and, if possible, the other two as well. We had originally thought that we would simply modify the platform NewItems() call to have a way to say “link all of these together using related items”, but it turns out that there’s no simple way to do that, and the complex ways have architectural implications we don’t like.

So, we’re considering a different scheme. In this scheme, rather than linking together using the platform-generated key (ie CommonData.Key.Id), we would link together using an application-generated client-id instead. So, to link two items together, you would do the following:

  1. Create instance of object a

  2. Create instance of object b

  3. a.CommonData.ClientId = Guid.NewGuid();

  4. b.CommonData.RelatedItems.Add(a.CommonData.ClientId);

  5. b.CommonData.ClientId = Guid.NewGuid();

  6. a.CommonData.RelatedItems.Add(b.CommonData.ClientId);

  7. Call NewItems and pass in both instances

We would likely provide a helper function to do #3 – #6, so you could merely write “MakeThingsRelated(a, b)”, and the helper would do all the work of generating the client ids and hooking them up.

We would also modify “GetItem” to retrieve an object either using the Key.Id or the Client id, and the code you would write to fetch the related items would be the same as what you currently write.

There are three disadvantages to this approach that we see:

  1. The client id isn’t invariant, so it’s possible for me to set up a related item and then have another app come along and change the client id, breaking the related item. However, apps can already delete the related item or remove an entry from the related item list, so I don’t think it’s really any different than our current behavior.

  2. GetItem() currently takes a instance Id, and in the new world it would take either an instance ID or a client ID. That means that it’s a little more confusing to developers to figure out what is going on when they look at code.

  3. HealthRecordItemRelationship now holds two different kinds of information, and you have to know which is which. I think that with a bit of encapsulation, we can make the impact of this to be small.

We could avoid #2 and #3 by adding a new method to fetch an item by clientId (ie GetItemByClientId()). That would make that api clearer, but would have the unfortunate byproduct of requiring a rewrite of all existing code that uses related items to be able to deal with client-related items (it would need to know whether to call GetItem() or GetItemByClientId()…).

We’re leaning towards doing the client-id approach, but would like any thoughts you might have.

Comments (1)

  1. John Lohan says:

    Hello Eric,

    I don’t think introducing ClientId makes the problem any simpler. Rather, I’m more comfortable with the current implementation. Less the number of GUIDs we come accross, less the confusion.

    But let me tell you my main concern.

    I can relate one thing with another, but how do I specify what is the relationship?

    E.g. I can relate an Allergy with a Procedure. But how do I specify that the related GUID is referring to an allergy?

    Say, I use RelationshipType string.

    But how will the other applications know what is the meaning of the string?

    Also, how do I know that this relationship was added by me? In this case, every application should carefully prefix the RelationshipType string with some unique string (e.g. name of the application).

    This doesn’t sound a good mechanism, since we are at the discretion of each and every application using HV.

    As per my opinion, we should have another member of HealthRecordItemRelationship class named RelatedItemType of type HVThingTypesEnum, which is an enum of all the thing types (including application-specific).

    And preferably it should be a non-nullable field.

    Let me know if you thing this will add any value.