FHIR Chat · ValueSet for element and direction · implementers

Stream: implementers

Topic: ValueSet for element and direction


view this post on Zulip Michael Donnelly (May 15 2018 at 13:38):

In the FHIR Connectathon Clinical Notes track (discussion here: https://chat.fhir.org/#narrow/stream/58-connectathon-mgmt/subject/Clinical.20Notes.20Track), we wrestled with an issue that we think will become more prevalent the more common FHIR writes become.

view this post on Zulip Michael Donnelly (May 15 2018 at 13:39):

If a client reads a resource, and an element in the resource has a code the client doesn't know, the client still got the resource.

view this post on Zulip Michael Donnelly (May 15 2018 at 13:40):

This isn't ideal, but the client can work on mapping after the fact or can use the other elements of the resource if that's all the client needs.

view this post on Zulip Michael Donnelly (May 15 2018 at 13:40):

But if a client attempts to write to a server and includes an element with a value the server doesn't know, the server is likely to refuse to file the resource.

view this post on Zulip Michael Donnelly (May 15 2018 at 13:41):

So it's important that a client be able to discover what values the server will accept.

view this post on Zulip Michael Donnelly (May 15 2018 at 13:43):

The two elements we struggled with in the Clinical Notes track were DocumentReference.type and DocumentReference.content.attachment.contentType.

view this post on Zulip Michael Donnelly (May 15 2018 at 13:45):

We could profile our systems, and a client could get the CapabilityStatement to find the StructureDefinition to find the ElementDefinition to find the ValueSet.

view this post on Zulip Josh Mandel (May 15 2018 at 13:48):

@Grahame Grieve mentioned something like an operation to ask GET /ValueSet/$supported-at?element=DocumentReference.type -- is this a real thing that's been defined before, or just an idea? (And if the latter... did I get the idea right?)

view this post on Zulip Michael Donnelly (May 15 2018 at 13:48):

This approach poses two challenges:
1. Both of the EHRs in the Clinical Notes FHIR Connectathon track support different subsets of MIME for contentType incoming and outgoing.
2. This approach is heavy. A client needs to hit multiple endpoints just to find out where the ValueSet it needs is. I fear this would be burdensome to client developers.

view this post on Zulip Michael Donnelly (May 15 2018 at 13:48):

Sorry, comments out of order.

view this post on Zulip Michael Donnelly (May 15 2018 at 13:49):

Yes, @Josh Mandel , that would work perfectly.

view this post on Zulip Michael Donnelly (May 15 2018 at 13:49):

It would also need to accept a direction or interaction type, since the incoming and outgoing ValueSet might not match.

view this post on Zulip Michael Donnelly (May 15 2018 at 13:50):

Do other people like @Josh Mandel's idea?

view this post on Zulip Josh Mandel (May 15 2018 at 13:51):

I think it'd need context, like

GET /ValueSet/$supported-at?element=DocumentReference.type&action=note.write

... in the general case, since the same elements will be be used in different contexts/activities

view this post on Zulip Michael Donnelly (May 15 2018 at 13:51):

Hmmm.

view this post on Zulip Michael Donnelly (May 15 2018 at 13:52):

True.

view this post on Zulip Josh Mandel (May 15 2018 at 13:52):

I mean, maybe not -- but even for reading vs writing notes I'm imagining different types might be supported.

view this post on Zulip Michael Donnelly (May 15 2018 at 13:52):

No, I think you're right.

view this post on Zulip Michael Donnelly (May 15 2018 at 13:52):

If someone is posting an Observation, different codes will be valid for labs or vitals.

view this post on Zulip Josh Mandel (May 15 2018 at 13:53):

Sure. Pretty quickly we get into a pseudo-profiling language though.

view this post on Zulip Michael Donnelly (May 15 2018 at 13:53):

Would it make sense to have a query parameter for http://hl7.org/fhir/valueset-type-restful-interaction.html and, as needed, another for category or whatever>

view this post on Zulip Michael Donnelly (May 15 2018 at 13:53):

?

view this post on Zulip Josh Mandel (May 15 2018 at 13:53):

Yeah, I think so.

view this post on Zulip Michael Donnelly (May 15 2018 at 13:54):

I think most of the time, all creates for a resource will accept the same ValueSet all the time for a given element.

view this post on Zulip Michael Donnelly (May 15 2018 at 13:54):

We could start with that and expand it if and when someone needs it.

view this post on Zulip Josh Mandel (May 15 2018 at 13:54):

Yup.

view this post on Zulip Michael Donnelly (May 15 2018 at 13:54):

I started roughing something out over the weekend: https://simplifier.net/supportedvalueset/unnamedoperationdefinition

view this post on Zulip Josh Mandel (May 15 2018 at 13:58):

Oh, cool!

view this post on Zulip Michael Donnelly (May 15 2018 at 13:58):

@Brett Marquard @Dennis Patterson @Danielle Friend @Andrew Torres

view this post on Zulip Michael Donnelly (May 15 2018 at 13:58):

What can I do to make it better?

view this post on Zulip Michael Donnelly (May 15 2018 at 14:00):

Does it make more sense to put the Resource and the element path into the same query parameter?

view this post on Zulip Josh Mandel (May 15 2018 at 14:00):

Two quick things

  • Deliver on your promise of "Example to come" :-)
  • Figure out how to make the url not say unnamedoperationdefinition

view this post on Zulip Josh Mandel (May 15 2018 at 14:01):

I think combining resource and element path isn't bad, given how pervasively ElementDefinition does this.

view this post on Zulip Michael Donnelly (May 15 2018 at 14:01):

  • Done
  • Ugh, I know. I need to figure that out.

view this post on Zulip Josh Mandel (May 15 2018 at 14:04):

@Christiaan Knaap do you know how to adjust the unnamedoperationdefinition path segment of https://simplifier.net/supportedValueSet/unnamedoperationdefinition/~overview ?

view this post on Zulip Michael Donnelly (May 15 2018 at 14:04):

https://simplifier.net/supportedvalueset/supported-at

view this post on Zulip Michael Donnelly (May 15 2018 at 14:04):

Figured it out. :)

view this post on Zulip Josh Mandel (May 15 2018 at 14:04):

Sweet!

view this post on Zulip Christiaan Knaap (May 15 2018 at 14:05):

Good that it apparently is discoverable how to do that.

view this post on Zulip Danielle Friend (May 15 2018 at 14:06):

How do we model the response so that it can support scenarios where there are 0 valuesets found or more than 1 valuesets found?

view this post on Zulip Josh Mandel (May 15 2018 at 14:07):

Hmm. @Danielle Friend one answer is that you always get one, which may be (in term) composed-of others. But I'd just as soon return a Bundle of 'em.

view this post on Zulip Michael Donnelly (May 15 2018 at 14:07):

I thought about this more, @Danielle Friend .

view this post on Zulip Michael Donnelly (May 15 2018 at 14:08):

Would it be better to return a Bundle or to allow the client to scope the request to make it clear which ValueSet it needs?

view this post on Zulip Josh Mandel (May 15 2018 at 14:09):

But the answer even for a very specific request could still be "none", or "these two are both good in your context".

view this post on Zulip Michael Donnelly (May 15 2018 at 14:09):

If we accept different values for Observation.code depending on the value in Observation.category, should there be a category parameter?

view this post on Zulip Danielle Friend (May 15 2018 at 14:09):

I think it would also be valuable to support - give me all valuesets you could return for x resource - not specified by path.

view this post on Zulip Michael Donnelly (May 15 2018 at 14:09):

If two are good in the same context, wouldn't that be one ValueSet?

view this post on Zulip Michael Donnelly (May 15 2018 at 14:10):

The compose can have multiple includes.

view this post on Zulip Josh Mandel (May 15 2018 at 14:10):

That's what I meant about composed-of -- you can always do that.

view this post on Zulip Josh Mandel (May 15 2018 at 14:10):

But it may not be the easiest thing to consume.

view this post on Zulip Michael Donnelly (May 15 2018 at 14:10):

Hmm.

view this post on Zulip Michael Donnelly (May 15 2018 at 14:10):

Good point.

view this post on Zulip Michael Donnelly (May 15 2018 at 14:11):

Okay, I'm willing to accept that even if I could dismiss this case, there may be others. And it's easier to make it return a Bundle now than to change it later.

view this post on Zulip Danielle Friend (May 15 2018 at 14:11):

I think that would be great to try out at a connectathon and get feedback on - all in one valueset of composed of, or separate value sets

view this post on Zulip Danielle Friend (May 15 2018 at 14:12):

Also, having no results definitely seems likely. I asked for Medication Create.. well thats not supported, we have no valuesets to return. It'd be nice to have this work like a search where you'd get an operation explaining why

view this post on Zulip Michael Donnelly (May 15 2018 at 14:12):

Sounds good.

view this post on Zulip Michael Donnelly (May 15 2018 at 14:12):

I'll change it.

view this post on Zulip Josh Mandel (May 15 2018 at 14:14):

Would we say something about whether the valuesets should (or shouldn't) be returned in expanded form? (I kind of think we shouldn't say anything -- but it's worth thinking through.)

view this post on Zulip Christiaan Knaap (May 15 2018 at 14:16):

Is it true that the client often already knows the few codes it could provide, and thus would just like to check whether any of those codes is acceptable? So add a parameter for a list of codes to check, and not return an entire (possibly large) valueset?

view this post on Zulip Josh Mandel (May 15 2018 at 14:17):

Yeah -- that almost feels like a different operation though (e.g., $code-supported-at?code=123&element=DocumentReference.type --> Boolean)

view this post on Zulip Christiaan Knaap (May 15 2018 at 14:19):

That would feel like a variant of $validate-code

view this post on Zulip Christiaan Knaap (May 15 2018 at 14:21):

And I meant multiple inputs / outputs:
$code-supported-at?code=123,xyz,bar,foo&element=DocumentReference.type -> xyz,foo

view this post on Zulip Michael Donnelly (May 15 2018 at 14:23):

That's an interesting angle @Christiaan Knaap. We hadn't thought of that.

view this post on Zulip Michael Donnelly (May 15 2018 at 14:23):

But I think it's valid.

view this post on Zulip Michael Donnelly (May 15 2018 at 14:24):

There are two use cases I envision for this:

view this post on Zulip Michael Donnelly (May 15 2018 at 14:24):

A. Someone wants to configure a client to work with a given server. For this, getting the whole ValueSet makes sense.

view this post on Zulip Michael Donnelly (May 15 2018 at 14:25):

B. The client wants to confirm that the server will do what it needs. For this, your idea makes more sense.

view this post on Zulip Michael Donnelly (May 15 2018 at 14:25):

Variant of B: an early step in automated testing.

view this post on Zulip Michael Donnelly (May 15 2018 at 14:26):

Mmm. And now I'm thinking of more cases (or variants) for it. Yeah, I think that's good.

view this post on Zulip Christiaan Knaap (May 15 2018 at 14:26):

Loosely connecting to the conversation in the room: is A also doable by specifying a specialized valueset in a profile that the server conforms to?

view this post on Zulip Michael Donnelly (May 15 2018 at 14:27):

Currently, I don't believe so without extensions.

view this post on Zulip Michael Donnelly (May 15 2018 at 14:28):

If a server has two profiles that each define a ValueSet for the same element, the allowed values for that element are the intersection of the ValueSets.

view this post on Zulip Michael Donnelly (May 15 2018 at 14:28):

@Dennis Patterson, you found that rule, right?

view this post on Zulip Christiaan Knaap (May 15 2018 at 14:30):

"Server has two profiles" or resource.meta.profile mentions 2 profiles?
Server may host 100 profiles for the same resourcetype, and then it would be useful if it could host the superset of the valuesets in the various profiles.

view this post on Zulip Christiaan Knaap (May 15 2018 at 14:31):

I do agree btw that calling an operation for A is probably a lot easier for a client.

view this post on Zulip Josh Mandel (May 15 2018 at 14:31):

And not for (B) ?

view this post on Zulip Christiaan Knaap (May 15 2018 at 14:32):

Yes, also for B, I did not even suggest an alternative for B :-)

view this post on Zulip Brian Postlethwaite (May 15 2018 at 14:39):

If the valueset has 32k concepts (e.g. observation, or some other really large valueset - we have a valuset with employer names that's 88k long) and as such wouldn't want that returned complete from the query.
From a client perspective if I'm trying to render some form of control with this, I'd need to have some form of indication that the potential results size.
And I'd want to know if I should be using $expand to dynamically get my values in a lookahead style interface, or a radio button set, or combo etc.

view this post on Zulip Josh Mandel (May 15 2018 at 14:47):

That's true. And in other contexts (offline db-populating), full expansion is fine.

view this post on Zulip Michael Donnelly (May 15 2018 at 14:47):

https://simplifier.net/supportedvalueset/code-supported-at

view this post on Zulip Josh Mandel (May 15 2018 at 14:48):

That's clever (taking a set in, returning the valid subset). I think you may need support for Coding in addition to Code, for the use cases we've been discussing (e.g. Observation.code, DocumentReference.type).

view this post on Zulip Michael Donnelly (May 15 2018 at 14:49):

It was Christiaan's idea. :)

view this post on Zulip Michael Donnelly (May 15 2018 at 14:51):

What's the most elegant way to do that, Josh?

view this post on Zulip Josh Mandel (May 15 2018 at 14:51):

Might take a list of codes in, and a list of codings in... Then put a list of codes out and a list of codings out?

view this post on Zulip Josh Mandel (May 15 2018 at 14:52):

But then you have to back the input cardinalities off to 0..* (from 1..*).

view this post on Zulip Michael Donnelly (May 15 2018 at 14:52):

What do we lose by changing it to a string?

view this post on Zulip Josh Mandel (May 15 2018 at 14:53):

Strings like http://loinc.org|123-4 ?

view this post on Zulip Dennis Patterson (May 15 2018 at 14:53):

@Michael Donnelly (to your earlier question) if you want to have separate profiles to dictate input vs output ValueSets for a field, I came across two issues with specifying this w/conformance.

One, if you wanted your CapabilityStatement to list two rest.resource structures for the same resource type (e.g. one for DocumentReference create and one for DocumentReference search/read), the comment on CapabilityStatement.rest.resource says "Max of one repetition per resource type."

Two, documentation on supporting multiple profiles says "The impact of supporting two sets of profiles depends on whether resources are being created or consumed. When an application is creating content, it must create content that conforms to both sets of profiles - that is, the intersection of the profiles.". We're talking about two ValueSets that are currently non-intersecting, so this kind of thing doesn't seem supported.

view this post on Zulip Josh Mandel (May 15 2018 at 14:55):

@Dennis Patterson I don't think these considerations apply to CapabilityStatement.rest.resource.supportedProfile though

view this post on Zulip Dennis Patterson (May 15 2018 at 14:56):

What about the first limitation? Is it valid to express separate profiles for separate actions?

view this post on Zulip Josh Mandel (May 15 2018 at 14:56):

You can list a set of profiles (e.g. for Observation: vitals + labs) in a single list, in a single CapabilityStatement.rest.resource entry.

view this post on Zulip Michael Donnelly (May 15 2018 at 14:57):

What's the point of having an element that's a code instead of a string in any Resource? Because in the definition of the Resource you can specify the binding, and clients and servers will know what's supposed to be in there.\

view this post on Zulip Dennis Patterson (May 15 2018 at 14:58):

Yes you can link to multiple StructureDefinitions, but can you specify that they are for different actions?

view this post on Zulip Michael Donnelly (May 15 2018 at 14:58):

In this case,
1. We can't specify a binding in the definition, since it could be anything.
2. The whole purpose of the operation is that we know the code/coding might be wrong.

view this post on Zulip Josh Mandel (May 15 2018 at 14:58):

Practically that seems fine -- though technically FHIR OperationDefinitions don't provide a way to convey a Coding in a GET parameter, I think.

view this post on Zulip Michael Donnelly (May 15 2018 at 14:59):

Hmm.

view this post on Zulip Michael Donnelly (May 15 2018 at 14:59):

It's like a token search parameter.

view this post on Zulip Josh Mandel (May 15 2018 at 15:00):

It totally could be like that. I just don't think we've specified it.

view this post on Zulip Dennis Patterson (May 15 2018 at 15:00):

Yes, we want simple ways to be able to allow consumers to identify what codes are supported for specific fields (for different contexts such as an action). I'm just trying to find out whether it's possible to advertise this (tell, not just answer).

view this post on Zulip Michael Donnelly (May 15 2018 at 15:05):

Looks like OperationDefinition.parameter.searchType can be token.

view this post on Zulip Michael Donnelly (May 15 2018 at 15:07):

So I changed the type for the "code" parameter to string and added a searchType of token.

view this post on Zulip Michael Donnelly (May 15 2018 at 15:09):

There isn't a way to do that in the value returned, though.

view this post on Zulip Michael Donnelly (May 15 2018 at 15:09):

Should it just have code and coding elements in the response?

view this post on Zulip Michael Donnelly (May 15 2018 at 15:11):

Like this? https://simplifier.net/supportedvalueset/code-supported-at

view this post on Zulip Eric Haas (May 15 2018 at 16:33):

Sounds to me like the original ask could be defined in the Profile with an read/write extension on the valueset elements. Hey @Rob Hausam have you looked at this issue ... isn't this what the TerminologyCapabilities supposed to address?

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

so, this thread jumped ahead a long without me.

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

the existing operation that @Josh Mandel originally referred to is

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

GET [base]/ValueSet/$expand?context=DocumentReference.type

That is - give me the value set expansion for the value set you use in the context DocumentReference.type

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

the idea that there are different value sets for reading or writing is foreign to FHIR so far; neither this operation nor CapabilityStatement considers this as a possibility. And I'm still not sure that I fully understand why the value sets are different

view this post on Zulip Eric Haas (May 15 2018 at 21:24):

As I understand For Binary, Server A accepts mimetype x,y and z on a POST but only displays mimetype x on a GET.

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

so why is it important to know that it only returns x?

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

does the server allow you to ask for a particular format?

view this post on Zulip Michael Donnelly (May 15 2018 at 22:23):

Good question. Knowing what incoming values a server will accept is crucial. Knowing what values it might return is not as important.

view this post on Zulip Michael Donnelly (May 15 2018 at 22:25):

We've encountered client vendors who want to know all the values they might need to map - all the outgoing values from the server - so they can do the work ahead of time to make sure they'll all work well.

view this post on Zulip Michael Donnelly (May 15 2018 at 22:25):

I'd like to be able to meet that desire of theirs, and I really don't want to mislead them into thinking there's a different set of values they might receive than what they actually could.

view this post on Zulip Eric Haas (May 15 2018 at 22:30):

I know you all considered an 'in/out/both' extension on the valueset.concept. why was that idea discarded? Cause then is baked into the profile.

view this post on Zulip Michael Donnelly (May 15 2018 at 23:11):

I think both angles are useful. A way to make it from CapabilityStatement all the way down to the ValueSet, and a way to go back up from an element to the ValueSet.

view this post on Zulip Grahame Grieve (May 16 2018 at 04:39):

so Michael, your operation goes way beyond in/out - is that neecssary?

view this post on Zulip Grahame Grieve (May 16 2018 at 04:40):

GET [base]/ValueSet/$expand?context=DocumentReference.type&operation=read

view this post on Zulip Grahame Grieve (May 16 2018 at 04:40):

we could do that. And default to the superset, I supppose.

view this post on Zulip Michael Donnelly (May 16 2018 at 07:18):

No, I don't think so. I think we could have incoming (for update, patch, create, and search-type) and outgoing (for read, vread, history-instance, and history-type). Anyone thing we need more granularity than incoming/outgoing? @Dennis Patterson @Danielle Friend @Brett Marquard @Andrew Torres @Josh Mandel @Isaac Vetter ?

view this post on Zulip Michael Donnelly (May 16 2018 at 07:24):

@Grahame Grieve, is there an existing ValueSet we can use for incoming/outgoing?

view this post on Zulip Drew Torres (May 16 2018 at 07:25):

I think inbound vs outbound would meet the need.

view this post on Zulip Josh Mandel (May 16 2018 at 07:26):

But as discussed above... do we actually want to expand in this use case?

view this post on Zulip Josh Mandel (May 16 2018 at 07:26):

If so, then this operation looks like a good fit.

view this post on Zulip Danielle Friend (May 16 2018 at 07:27):

I can't think of a reason we'd need more than in/out.

view this post on Zulip Michael Donnelly (May 16 2018 at 07:39):

Could ValueSet/$expand handle @Christiaan Knaap's case by passing in the value you want to check as a filter?

view this post on Zulip Christiaan Knaap (May 16 2018 at 09:08):

No, that would be more like $validate-code but with a context provided I think. But that only allows for 1 input, and essentially true/false as return.

view this post on Zulip Michael Donnelly (May 16 2018 at 09:08):

Ah, makes sense.

view this post on Zulip Grahame Grieve (May 16 2018 at 09:19):

sure $expand does that. You definitely want an expand for this

view this post on Zulip Grahame Grieve (May 16 2018 at 09:19):

there's no an existing value set. I'll see if I can implement this on my server tonight

view this post on Zulip Dennis Patterson (May 16 2018 at 10:27):

TL;DR Patient vs Provider or API limitations may scope inputs narrower than outputs. Can this be more holistically supported by allowing CapabilityStatement.rest.resource to have separate profiles for inputs vs outputs?

Thought it would be helpful to provide some additional use-case details:

  • Patients will usually have a narrower scope of what can be created than Providers.
  • Providers may have narrower scope of what can be created through FHIR than by native means

This can factor in resources such as...
- DocumentReference.content.attachment.contentType - only create documents of certain types. Cerner and Epic systems transform the content into another type for storage
- Appointment.appointmentType - only support creation of certain appointment types
- Patient race extension - only allow certain races/ethnicities to be written (e.g. clients/customers may only want certain races to be written in their systems going forward)

@Grahame Grieve stated "the idea that there are different value sets for reading or writing is foreign to FHIR so far; neither this operation nor CapabilityStatement considers this as a possibility." So, the Conformance resources as a whole do not support this. Since that's the underlying reality, it causes problems when trying to expose this through $expand.

First, introducing an interaction/operation parameter to $expand doesn't agree with the fundamental assumptions of FHIR and creates a mismatch.

Second, from what I've read on $expand, context is recommended to include a StructureDefinition. The proposal so far removes that in favor of just an element path. This seems to avoid the issue that separate profiles for inputs/outputs are discouraged.

All in all, we (Cerner and Epic) are wrestling with identifying the best solution, as well. And, if this is supported first-hand, wanting to be aware of what other implications this has to the spec. Are there any reasons not to change CapabilityStatement.rest.resource uniqueness from resource type only, to type + interaction?

view this post on Zulip Michael Donnelly (May 16 2018 at 11:45):

Or type+direction.

view this post on Zulip Grahame Grieve (May 16 2018 at 12:21):

well, for those interested, we'll be talking about capability statement this evening. contact me if you're interested.

view this post on Zulip Grahame Grieve (May 16 2018 at 12:22):

I think type+direction is better than type+interaction, but I'm interested to know whether anyone would propose that delete is special again (e.g. I only delete cancelled things...)

view this post on Zulip Grahame Grieve (May 16 2018 at 14:03):

@Dennis Patterson:

First, introducing an interaction/operation parameter to $expand doesn't
agree with the fundamental assumptions of FHIR and creates a mismatch.

not sure whether you are echoing me or not, and not sure whether you are agreeing or not. I was making a statement about the past, but not necessarily proposing a rule for the future.

Second, from what I've read on $expand, context is recommended to include
a StructureDefinition.

You're right; I ducked that part for this purpose, though to be closely following the documentation, I'd have to add an argonaut specification profile url - but I don't know what that is.

This seems to avoid the issue that separate profiles for inputs/outputs
are discouraged.

I'm not saying they are discouraged. Just foreign to our work to this point. We'll be talking about this amongst other things tonight

view this post on Zulip Michael Donnelly (May 16 2018 at 14:07):

Delete might well have differences, but that's in the business logic behind it rather than code mapping. I think we're okay there.

view this post on Zulip Grahame Grieve (May 16 2018 at 15:04):

ok, working... just have to upgrade soon

view this post on Zulip Michael Donnelly (May 16 2018 at 16:02):

The profile won't be an Argonaut profile, it'll be for the specific organization in question. The list of note types, for example, is owned by each organization using Epic or Cerner.

view this post on Zulip Grahame Grieve (May 16 2018 at 18:29):

@Michael Donnelly : http://test.fhir.org/r3/ValueSet/$expand?context=DocumentReference.type&operation=read

view this post on Zulip Grahame Grieve (May 16 2018 at 18:30):

can't ask the client to figure out the profile URL - they can, but they might as well use the long path to that value set

view this post on Zulip Grahame Grieve (May 16 2018 at 18:40):

and also http://test.fhir.org/r3/ValueSet/$expand?context=DocumentReference.type&operation=write

view this post on Zulip Michael Donnelly (May 16 2018 at 23:16):

That looks great, Grahame.

view this post on Zulip Michael Donnelly (May 16 2018 at 23:17):

My remaining concerns are totally nitpicky - functionally this does what we need.

view this post on Zulip Michael Donnelly (May 16 2018 at 23:18):

Should we have a name other than "operation" for the search parameter, since Operator means something in FHIR? And should we have a ValueSet that doesn't include "read" since that's a thing in REST? (And also because when you pass a value in for a search, that's incoming but isn't actually writing.)

view this post on Zulip Michael Donnelly (May 16 2018 at 23:19):

I think "incoming" and "outgoing" make sense for the values, but I have no idea for the parameter.

view this post on Zulip Grahame Grieve (May 17 2018 at 04:28):

I considered: mode, interaction, operation, verb, scope

view this post on Zulip Grahame Grieve (May 17 2018 at 04:29):

I'm ok with in/out or incoming/outgoing

view this post on Zulip Grahame Grieve (May 17 2018 at 04:30):

but thinking more generally about this... it's about what you are doing with the element that you named in the context... I'm... searching on it? (context = search parameter?)

view this post on Zulip Michael Donnelly (May 17 2018 at 07:15):

Context feels right. Is there a way we can use "context" without blowing up the scope of this?

view this post on Zulip Grahame Grieve (May 17 2018 at 07:18):

well, for this, we can scope it exactly how we want... not sure I've understood your question correctly

view this post on Zulip Michael Donnelly (May 17 2018 at 07:19):

I think you've got it right.

view this post on Zulip Michael Donnelly (May 17 2018 at 07:21):

I wouldn't want to take the time now to define every sort of context. But if we can define context of "incoming" and "outgoing" now and add additional context later as needed, that sounds perfect.

view this post on Zulip Michael Donnelly (May 17 2018 at 07:22):

@Dennis Patterson how does this work for you? @Danielle Friend and I were more concerned about the lookup, and Grahame's $expand works great for that.

view this post on Zulip Michael Donnelly (May 17 2018 at 07:25):

What would this look like? http://fhir.example.org/r3/ValueSet/$expand?context=DocumentReference.type&context=incoming ?

view this post on Zulip Dennis Patterson (May 17 2018 at 08:16):

ValueSet's $expand operation is typically expanding a specific ValueSet, yes? By removing profile from the context parameter, is there ever any ambiguity of what ValueSet should be expanded? I'm thinking through specific, narrow use-cases, but just trying to make sure the operation holds up for others

view this post on Zulip Michael Donnelly (May 17 2018 at 08:25):

If there's ambiguity, should the server return an error indicating that the client should specify additional context?

view this post on Zulip Grahame Grieve (May 17 2018 at 09:14):

server has to return an error, yes

view this post on Zulip Grahame Grieve (May 17 2018 at 09:22):

we omitted profile, yes. I did that because, in fact, there's no prefixed value that the client could know in advance that they could use, and because if they had to find it, they might as well look up by the long path we first laid out (CapabilityStatement -> StructureDefinition -> ValueSet). Also, none of you indicated that there was any reason to think about different profiles in play on these elements. Hence, just easier to leave it out

view this post on Zulip Josh Mandel (May 17 2018 at 09:46):

Do we care about a use case where the EHR has a large value set, like "any valid LOINC code" for Observation.code? If so, forcing an expand operation may be undesirable.

view this post on Zulip Harald Aamot (May 18 2018 at 10:46):

Or type+profile.
use case would be to have a profile stating a narrower input than the output (example read certain Document types from cerner, convert them internally and offer profile specifying which content types are possible (broader output ))

if incoming[CREATE] and outcoming[READ] would be used, what about the use cases update/delete?

view this post on Zulip Yunwei Wang (May 18 2018 at 15:02):

Just to clarify, this discussion is about operation on EHR server, not on Terminology Server.

view this post on Zulip Grahame Grieve (May 18 2018 at 18:45):

well, the EHR has the discretion to return that the operation is too costly. The terminology servers routinely do this when the value set exceeds a certain cut-off size.

view this post on Zulip Grahame Grieve (May 18 2018 at 18:50):

@Yunwei Wang it's an API; the terminology server could support that on behalf of the EHR

view this post on Zulip Yunwei Wang (May 21 2018 at 23:48):

@Grahame Grieve I am worrying that if one terminology server serves multiple EHR servers, how the terminology server knows the correct context.

view this post on Zulip Grahame Grieve (May 21 2018 at 23:50):

it wouldn't, from that call. that would have to be established in the context.

view this post on Zulip Grahame Grieve (May 21 2018 at 23:50):

I don't think it should be the client's problem....

view this post on Zulip Yunwei Wang (May 22 2018 at 02:05):

I don't think this is a client's problem either. Instead, EHR server should be able to map the context to valueset ID and redirect the query to terminology server to expand with the correct id.

view this post on Zulip Grahame Grieve (May 22 2018 at 04:16):

which is exactly how my server resolves this one internally

view this post on Zulip Brett Marquard (Jun 05 2018 at 09:50):

This is a great discussion I am only a few weeks late to -- @Grahame Grieve, Acceptable to create a tracker to update the $expand operation? Do we need an indicator on the value set on whether a value set is incoming vs outgoing? I am a little fuzzy how we expect servers to keep track

view this post on Zulip Rob Hausam (Jun 05 2018 at 13:12):

It would probably be good to discuss this on the terminology stream. I'm not sure if we want/need an incoming vs outgoing indicator, but it is something that we should consider.

view this post on Zulip Grahame Grieve (Jun 05 2018 at 13:49):

definitely need it for this use case. It would be associated with the element property, not more generally with the value set expansion framework

view this post on Zulip Grahame Grieve (Jun 05 2018 at 13:49):

and yes please create ta task

view this post on Zulip Brett Marquard (Jun 05 2018 at 20:37):

can you say more about how it would be associated with the element property?

view this post on Zulip Grahame Grieve (Jun 06 2018 at 03:03):

see http://build.fhir.org/valueset-operation-expand.html - the context parameter.

view this post on Zulip Grahame Grieve (Jun 06 2018 at 03:03):

would be another parameter that would be used with that parameter

view this post on Zulip Brett Marquard (Jun 06 2018 at 14:22):

Thanks, I am a little stumped is how a client knows to even ask the question about available write/read options. #GF17321

view this post on Zulip Michael Donnelly (Jun 06 2018 at 15:30):

I don't think a client will ask for a valueset at runtime (or, really, workflow time). Rather, the administrator who sets up a client will use it to configure the client to do what the server needs.

view this post on Zulip Brett Marquard (Jun 06 2018 at 18:30):

Grahame, did you mean to implement at DocumentReference.context.attachement.contentType instead of DocumentReference.type?

view this post on Zulip Grahame Grieve (Jun 06 2018 at 19:59):

yes my mistake.

view this post on Zulip Grahame Grieve (Jun 06 2018 at 20:00):

not sure about the client knowing to ask?

view this post on Zulip Michael Donnelly (Jun 12 2018 at 14:16):

@Rob Hausam it looks you documented the Resolution text of #GF17321 from the Vocab meeting yesterday but not the Ballot Resolution. Should this be Persuasive? @Grahame Grieve @Brett Marquard

view this post on Zulip Rob Hausam (Jun 12 2018 at 16:26):

I didn't get to that on the call yesterday, but was going to do that when I included it in the block for the main vocab call - done.

view this post on Zulip Colby Seyferth (Aug 08 2018 at 23:30):

There seem to be two reasonable ways to return the list of codes in the ValueSet Resource: under the compose element, and under the expansion element.

@Grahame Grieve , in your example $expand query, the response ValueSet used the expansion element (and elements under the expansion) to return the supported codes http://test.fhir.org/r3/ValueSet/$expand?context=DocumentReference.type&operation=read

Is it also reasonable to use the compose element, where you would get a response like this: valueSetResponse.txt ?

I wanted to get you guys' opinion because it seemed like the expansion element was made specifically for this operation, however I was not sure if it was necessary.

The ValueSet.Read interaction would return the same resource as the $expand in this case.

view this post on Zulip Grahame Grieve (Aug 08 2018 at 23:43):

compose may or may not contain a list of codes, and the list may or may not be correct in any given context.

view this post on Zulip Grahame Grieve (Aug 08 2018 at 23:44):

it's the definition of what should be in the value set, given a set of additional rules about context

view this post on Zulip Grahame Grieve (Aug 08 2018 at 23:45):

to actually figure out what is in the value set under the applicable rules, some engine evaluates them, and creates a value set with the expansion populated that contains the actual list. So: you should only use the compose element if you're dealing with the rules, not the actual outcome. Sounds to me like you want expansion

view this post on Zulip Colby Seyferth (Aug 09 2018 at 17:28):

I didn't realize that is what compose meant, and don't really understand how it is useful, but I've updated the response to use the expansion element: valueSetResponse2.txt

Thanks for clearing that up.

view this post on Zulip Colby Seyferth (Jan 28 2019 at 15:35):

@Grahame Grieve Following up on this. For the response to an $expand query, I'd return the list of codes/systems under the "expand" element. From your comment above, I am inferring that I would also want to use the "expand" element when doing a read on the ValueSet resource to get a list of codes. Is that correct, or in the case of a Read interaction, would it be appropriate to return the codes under the "compose" element?

view this post on Zulip Grahame Grieve (Jan 28 2019 at 19:25):

if you want to get the list of code in a value set, you should always use $expand

view this post on Zulip Yunwei Wang (Jan 29 2019 at 23:03):

Read ValueSet returns ValueSet definition. $expand operation returns ValueSet expansion.

view this post on Zulip Colby Seyferth (Jan 31 2019 at 23:47):

Makes sense. Another question that affects FHIR more broadly, but is encountered with a ValueSet Expansion: What do we do if there are too many values in an expansion to return them all at once?

FHIR has a through guide to paging when the response is a bundle of many resources. But if there is a single resource with thousands of repeating elements, how can we return them all in a single response? This could be an issue for ValueSet.$expand, and we've also seen it with the List resource.

view this post on Zulip Grahame Grieve (Jan 31 2019 at 23:49):

you can page through an expansion - check the $expand parameters

view this post on Zulip Colby Seyferth (Feb 01 2019 at 00:13):

Ohh, I see; that is convenient. It seems a little weird to pass an integer as the offset as opposed to just using a session ID to just start where you left off from, since the contains elements don't seem like they are supposed to be in any particular order.

I guess the offset could be nice if you are just looking for the last few codes? Is the idea that the client would do a $expand with count=0 to find out if there are any new codes...

view this post on Zulip Colby Seyferth (Feb 01 2019 at 00:14):

wait, nvm, because even if they do the $expand?count=0 and find out that there are new codes, it doesn't mean they are added to the end (since they arent ordered), so they will have to expand the whole valueset from the beginning to get the missing codes.

view this post on Zulip Colby Seyferth (Feb 01 2019 at 00:14):

The "total" element is the number of codes the server has, not the number of codes returned with this $expand request, right?

view this post on Zulip Grahame Grieve (Feb 01 2019 at 00:49):

yes to all that

view this post on Zulip Yunwei Wang (Feb 01 2019 at 15:24):

If count = 0, the client is asking how large the expansion is. My understanding is that server returns only the total number.

view this post on Zulip Colby Seyferth (Feb 01 2019 at 20:35):

why do we make the client keep track of the count and offset to do paging? It seems like it just adds a level of complexity (sure addition and keeping track of a number is pretty simple, but I'd think it is not needed).

Is there a use case that is not "just give me all the codes" which would benefit from having the offset relate to the number of codes not the number of pages?

view this post on Zulip Grahame Grieve (Feb 01 2019 at 20:40):

doing it by page count would force the page count itself to be a reliable agreement. And feedback was that clients to not necessarily want a consistent size for the page. (particularly first to second apge size)

view this post on Zulip Colby Seyferth (Feb 01 2019 at 20:55):

What if instead of a page count, you just had a reference to the "next" page, like how other paging works? That would be the easiest because you don't have to keep track of anything. The next URL is just right there in the response. And page size doesn't matter anymore either.

view this post on Zulip Grahame Grieve (Feb 01 2019 at 20:57):

well, there's quite some complications here. the server has to keep quite a lot of state for the search based mechanism, in order to get it right. Not all servers do, in fact. We wanted to avoid the need for state in this case

view this post on Zulip Colby Seyferth (Feb 01 2019 at 21:26):

What do you mean by the server has to keep quite a bit of state? The server just hasto keep track of the count and the offset. If we expect clients to be able to keep track of these two integers, a server should be able to as well.

Does this make it harder to page with ValueSet than it is to page with any other resource?

view this post on Zulip Grahame Grieve (Feb 01 2019 at 21:34):

not only does the server have to keep track of count and offset, the server has to reproduce the same result set to apply the offset to. In search, that can be quite problematic. We decided to duck that in value set expansion, and make the client specify the whole search each time, and a window into it

view this post on Zulip Colby Seyferth (Feb 12 2019 at 21:13):

not only does the server have to keep track of count and offset, the server has to reproduce the same result set to apply the offset to.

The rate-determining step here is producing the result set. Keeping track of an extra integer seems super trivial.

Why not just allow the client to pass a parameter that will let the server look up all of the state from the previous complex result set generation instead of just the offset? This could save the server a bunch of time, especially for a potentially costly operation.

view this post on Zulip Yunwei Wang (Feb 12 2019 at 21:51):

$expand returns one ValueSet resource. Search returns a bundle of resources.

view this post on Zulip Colby Seyferth (Feb 12 2019 at 23:40):

Right, well $expand returns part of a resource. If there are too many codes in the valueSet, the server can return the first 100 codes and then the Client will have to expand the ValueSet again to see codes 101 through 200.

The debate is: How should this paging of codes within a single ValueSet resource be done. I think we should just have a pointer to the next page of results so we can save the state from the previous expansions.

If the client only passes an "Offset" integer N, (unless the server stores all of the codes in a static table), the server may have to enumerate over the first N codes just to get to the offset spot where they will start. So when the client just wants the 1,000,001st code, the server has to enumerate over the first 1,000,000 codes to get to the last one.

view this post on Zulip Yunwei Wang (Feb 13 2019 at 03:28):

We save expansion in database. So it is much easier for us if client specifies offset and count.

view this post on Zulip Grahame Grieve (Feb 13 2019 at 11:08):

but if you do that, you can also add a state parameter that refers to the database record.

view this post on Zulip Grahame Grieve (Feb 13 2019 at 11:10):

I don't feel strongly about this. I only cache these things transiently, not in the database, but I could use a state parameter. However the technical specification for search paging (using links) doesn't seem so obviously applicable to $expand, since there's no bundle. Probably further discussion on this should be on the terminology stream with the other terminology server authors

view this post on Zulip Colby Seyferth (Feb 15 2019 at 21:16):

We save expansion in database. So it is much easier for us if client specifies offset and count.

I agree that if the expansion is stored in an index-able format in the database, or if we cached the whole expansion, it makes sense to just use the offset param. However, not all servers work that way, and the given $expand parameters should not dictate how the server has to store the expansion in their system. We could just cache the entire expansion too, but it could be pretty large, so it'd be cleaner for us to just iterate over codes in the DB.

I'm not suggesting using the "link" in a bundle, since that doesn't make sense for our non-bundle scenario. There should just be a sessionID-esque parameter instead of mandating paging by offset param. This "session ID" (or paging ID) param could just literally be the offset integer for servers like Yunwei's that are indexed, so nothing would change for them. And it could be a state identifier code for servers that want to iterate from where they last left off (as opposed to from a specific integer index).

view this post on Zulip Michael Lawley (Feb 25 2019 at 07:10):

The key difference is that a state parameter encodes all the $expand parameters, not just offset & count

view this post on Zulip Colby Seyferth (Feb 25 2019 at 16:22):

Isn't that even easier? When would the client want to use a different value for one of the other parameters?

view this post on Zulip Grahame Grieve (Feb 25 2019 at 23:26):

can we have this discussion just on the terminology stream?


Last updated: Apr 12 2022 at 19:14 UTC