FHIR Chat · temporary id · implementers

Stream: implementers

Topic: temporary id


view this post on Zulip Brian Reinhold (Jan 30 2017 at 13:13):

In a transaction Bundle one may have a resource that is referenced by another resource. However, the resource being referenced does not yet exist on the server so one uses a temporary id. A temporary id has the prefix "urn:oid:" or "urn:uuid:". Unlike a normal id the temporary id is not restricted to 64 characters so one can use a GUID. The question I have MUST the temporary id use an oid or GUID format OR may one use any of the legal characters of a normal id as long as it is unique within the Bundle?temporary id

view this post on Zulip Ewout Kramer (Jan 30 2017 at 14:18):

I don't think it's necessary to use oids, because
a) In a transaction: it's actually the receiver who determines whether the id is "new" and so whether it would be updated or created on a PUT
b) In a message/document, resolution (http://build.fhir.org/bundle.html#references) would do what you need, so here it does not seem to matter

view this post on Zulip Lloyd McKenzie (Jan 31 2017 at 01:15):

Well, the id has to be a urn it it's not a RESTful id. And the urn needs to be a valid urn. I actually think we do limit urns to OIDs and UUIDs, but I could be wrong on that. @Grahame Grieve ?

view this post on Zulip Brian Reinhold (Feb 01 2017 at 19:10):

Ewout,
It was my understanding that by definition a temporary id is going to be replaced by the server with something that the server finds appropriate. Furthermore this is the only way to do a POST in a transaction Bundle with a resource that is referenced by another resource in the Bundle. The "urn:iso:" or "urn:uuid:" prefix in the id is just a way to identify the id as a temporary id.

In that sense, it is never really part of a RESTful transaction. The transaction takes place after the server does the replacement. What I am wondering is if it really matters what I stick in there since it's just a placeholder whose value has no meaning. The only thing that is really needed is that it is unique within the Bundle. After the transaction no one would ever know what the original set of temporary ids was.

view this post on Zulip Lloyd McKenzie (Feb 01 2017 at 22:53):

If the resource already exists with a RESTful id - e.g. because you're doing an update rather than a create - then the id in a transaction can certainly be a real URL rather than a GUID. However, once the transaction is processed, there's no expectation that anyone will remember the GUIDs that were used

view this post on Zulip Brian Reinhold (Feb 03 2017 at 13:15):

I am not sure my question is understood. I am only considering the case where one has a transaction Bundle and does not know if the resource exists on the server OR knows that the resource does not exist on the server. So the transaction is either a create or a conditional create. In addition, there are other resources in the Bundle that reference this resource.
In this case I need to specify a temporary id. The question is are there any more restrictions on the temporary id other than it be unique within the Bundle? In other words, can I use "urn:oid:hello" as the temp id?

view this post on Zulip Lloyd McKenzie (Feb 03 2017 at 16:22):

urn:oid:hello isn't a valid urn:oid and some systems might choke. Normal convention is to use urn:uuid:[some guid]. Note that *any* url you specify in a transaction that doesn't have a base of the target server is going to be treated as a temporary id. If you have the resource on your server, you're free to use that URL - and the receiving system would usually establish a mapping between your id and the one it assigns.

view this post on Zulip Brian Reinhold (Feb 03 2017 at 16:32):

Okay, So that is the answer. They have to be valid oids or UUIDs. The reason temporary ids are being used is to avoid rejection by servers when one uploads a Bundle with create transaction and puts in a 'real' id (that will be changed). Doing so gave me errors. I am hoping that the temporary id will be accepted (it better be)!

view this post on Zulip Lloyd McKenzie (Feb 03 2017 at 16:34):

For a throw-away id, GUIDs meet the need much better than OIDs.

view this post on Zulip Grahame Grieve (Feb 06 2017 at 06:33):

I don't they have to be, but it's certainly better if they are. And safer

view this post on Zulip Grahame Grieve (Feb 06 2017 at 06:33):

btw, I didn't understand this:

view this post on Zulip Grahame Grieve (Feb 06 2017 at 06:33):

"Unlike a normal id the temporary id is not restricted to 64 characters so one can use a GUID"

view this post on Zulip Brian Reinhold (Feb 10 2017 at 17:49):

Graham, I was thinking of 128 bits which of course has nothing to do with the number of characters.
urn:uuid:47709cc7-b3ec-4abc-9d26-3df3d3d57907 is 45 characters. My bad.

On the other hand, when I try to actually USE a temporary id I get the following error
"Invalid placeholder ID found: urn:oid:1.0.0.1 - Must be of the form 'urn:uuid:[uuid]' or 'urn:oid:[oid]'"
Is that also my bad somehow or is this a bug in HAPI FHIR?

view this post on Zulip Lloyd McKenzie (Feb 10 2017 at 20:45):

Were you making that the "id" or the "full URL"? (The id is just the guid or OID, not the "urn:uuid:" part

view this post on Zulip Grahame Grieve (Feb 10 2017 at 22:50):

I think that urn:oid:1.0.0.1 is a valid oid, so it sounds like a bug, but where does it come from?

view this post on Zulip Brian Reinhold (Feb 11 2017 at 01:02):

Lloyd,
This is an example in from HAPI FHIR <fullUrl value="urn:uuid:47709cc7-b3ec-4abc-9d26-3df3d3d57907"/>
located here: http://hapifhir.io/doc_rest_client_examples.html#Transaction_With_Placeholder_IDs
Is the example in error? How does the server know that the id is a temporary id with the "urn:oid:" prefix?

view this post on Zulip Brian Reinhold (Feb 11 2017 at 01:04):

Grahame,
I got the same error when I used a GUID instead of my fake OID. Is Lloyd correct with respect to having no "urn:oid:" prefix? I would think it would be needed to tell the server that it is a temporaty id placeholder.

view this post on Zulip Lloyd McKenzie (Feb 11 2017 at 01:52):

The urn:oid: or urn:uuid: prefix appears in the fullUrl element of the Bundle entry. (And you'd only ever have an OID or UUID as the id inside a Bundle.)

view this post on Zulip Brian Reinhold (Feb 12 2017 at 10:53):

Lloyd,
That maybe a HAPI FHIR implementation issue. I put the urn:oid:* or urn:uuid:* (I have tried both) in the id in HAPI FHIR as that way I can access it later when I need to reference the resource in another resource. HAPI FHIR does not populate the id with that value in its final resource when it generates the Bundle. I also use that resource id when creating the full URL. So populating the resource id with the HAPI FHIR resource.setId() method is just implementation; the id is not present on the wire. It's clear HAPI FHIR uses the prefix to identify the id as 'temporary'

Nevertheless, no server accepts the temporary id, including the HAPI FHIR server, either version 2 or 3. I get that error above. If I remove the prefix, the id DOES get placed in both the resource AND the fullURL on the wire and the servers are happy. So it appears I need to violate the spec to function (as I understand it).

view this post on Zulip Lloyd McKenzie (Feb 12 2017 at 22:57):

@James Agnew Comments? :)

view this post on Zulip Grahame Grieve (Feb 13 2017 at 04:45):

may have resolved this in PM - some confusion about how references to temporary ids work

view this post on Zulip John Moehrke (Feb 14 2017 at 17:02):

warning UUID can be encoded two different ways in URN... The obvious way as a URN UUID. But there is a way to encode a UUID in OID form, which can then be encoded as URN OID... We should warn about this... We likely should require that UUID be encoded only using URN UUID form... https://healthcaresecprivacy.blogspot.com/2011/02/creating-and-using-unique-id-uuid-oid.html

view this post on Zulip James Agnew (Feb 14 2017 at 18:47):

does that actually matter? I don't think we actually draw a distinction between how we handle UUIDs and how we handle OIDs, so a UUID-encoded-as-OID shouldn't matter?

That is hilarious that that's a thing though.. learn something new every day.

view this post on Zulip Brian Reinhold (May 15 2018 at 19:47):

The temporary id used in create transactions in a Bundle is defined in HAPI FHIR. But I cannot locate where it is defined in the FHIR standards. Does anybody know where that specification is stated?

view this post on Zulip Lloyd McKenzie (May 15 2018 at 20:14):

http://build.fhir.org/bundle.html#bundle-unique

view this post on Zulip Brian Reinhold (May 15 2018 at 20:34):

It would have helped to define the term 'temporary id' there. Searching on temporary id led me to the remark in the FullURL description but that was as far as I got. In HAPI FHIR "urn:oid:" is also noted as exceptable and that is what I use...

view this post on Zulip Grahame Grieve (May 15 2018 at 21:35):

you could create a task for us to mention those words

view this post on Zulip Brian Reinhold (May 16 2018 at 13:07):

The other thing tjhat is unclear when using a temporary id is the relation between the resource logical id and the FullURL. When one is NOT using a temporary id, the FullURL will have "Resource/id". However, if id is a temporary id, should the FullURL have JUST the id OR shall it contain the resource name as well? For example, the Observation.id="urn:oid:1.0.0.5". Should the fullURL be "Observation/urn:oid:1.0.0.5" or just "urn:oid:1.0.0.5"?

view this post on Zulip Grahame Grieve (May 16 2018 at 13:47):

just the OID

view this post on Zulip Brian Reinhold (May 16 2018 at 13:54):

just the OID

Thank you!!

view this post on Zulip Brian Reinhold (Jul 12 2018 at 15:46):

As I understand it if I do a first-time conditional create of a Patient resource using a temporary id and reference that temporary id in an Observation resource in the bundle, the Patient resource will be created on the server. If I send another bundle with the same conditional create of the same Patient resource with a different temporary id and reference that temporary id in another Observation resource in the bundle, my understanding is that Patient resource will not be re-created (a 200 return not a 201) and the other Observation resource will reference the existing Patient resource on the server.

In other words, the server will take the logical id IT has created for the Patient, and place that in my new uploaded Observation resource.

Is this correct?

view this post on Zulip Chris Grenz (Jul 12 2018 at 17:24):

While server-specific logic might affect this, in general I would not expect the 2nd bundle to "know about" the first. The second bundle would POST a new Patient record rather than updating or linking to the Patient from the 1st bundle.

view this post on Zulip Brian Reinhold (Jul 12 2018 at 17:42):

While server-specific logic might affect this, in general I would not expect the 2nd bundle to "know about" the first. The second bundle would POST a new Patient record rather than updating or linking to the Patient from the 1st bundle.

@Chris Grenz I was hoping that would not be the case since I am using a conditional create. The server would see my second Patient resource but given that it is a conditional, it will look for a resource that matches it given the conditions (in this case the identifier). It would then return a 200 since it does not create the resource and I would think it would replace the temporary id with the id IT assigned to the Patient earlier and use that to update the temporary ids in the newly uploaded transaction bundle.

I suppose one way to find out is to do it. But I want to make sure the process is part of the conditional create standard (assuming the transaction is supported) and not unique to the server implementation.

view this post on Zulip Chris Grenz (Jul 12 2018 at 18:19):

My mistake - you're correct assuming your If-None-Exist header is set correctly.

view this post on Zulip Chris Grenz (Jul 12 2018 at 18:20):

Simply posting the same resource won't invoke that check.

view this post on Zulip Chris Grenz (Jul 12 2018 at 18:24):

I'd try it out on the test servers...there's some unspecified magic there. Probably worth a tracker item to be specific about the behavior you're describing.

view this post on Zulip Brian Reinhold (Jul 12 2018 at 18:43):

Simply posting the same resource won't invoke that check.

@Chris Grenz Not POST ... conditional create POST with a temporary id in a bundle

view this post on Zulip Chris Grenz (Jul 12 2018 at 18:45):

Conditional create = POST with If-None-Exist header.

view this post on Zulip Chris Grenz (Jul 12 2018 at 18:46):

In other words, I'm agreeing with you. As you describe should work.


Last updated: Apr 12 2022 at 19:14 UTC