FHIR Chat · cds-hooks: issue 10: Decide how services publish metadata · cds hooks

Stream: cds hooks

Topic: cds-hooks: issue 10: Decide how services publish metadata


view this post on Zulip CDS Hooks Bot (Mar 21 2016 at 21:26):

kpshek commented on issue 10

@Josh Mandel - I certainly am not a fan of trying to use the existing FHIR Conformance resource for this information so option 2 is my least preferred.

That leaves me with option 1. However, in your example above, it looks like a CDS Service is only able to communicate metadata on a particular activity (eg, medication-prescribe). I would think it would be preferable to communicate metadata about all activities offered up by the CDS Service.

So, I'll present another option, modified from my big *Thoughts on CDS Hooks* mailing list thread) and to take into account the decision that we will use the FHIR Parameters resource (see #11):

#### 3. Via $cds-hooks-metadata operation for all hooks

Simplified view:
Request: GET /$cds-hooks-metadata

{
  hooks:              1..* {
    hook:             1..1 valueCoding,
    url:              1..1 valueUri,
    name:             1..1 valueString,
    description:      1..1 valueString,
    preFetchTemplate: 0..* valueString
  }
}

I'm lazy so I'm omitting the full response using Parameters (which would be the actual response).

Changes from option 1:
- Support a list of hooks rather than just one
- Pluralize the operations name ($cds-hook-metadata to $cds-hooks-metadata
- Specify the URL for each hook
- Rename activity to hook (pending #13)

view this post on Zulip CDS Hooks Bot (Mar 21 2016 at 21:36):

jmandel commented on issue 10

Thank @kpshek. In the case where a single $cds-hook endpoint serves multiple different activities (medication-prescribe and patient-view, for example -- btw, see how using the word "hooks" there would have been akward?), I see the value in having a list of hooks.

But I'm not sure I understand the use case for giving each hook a separate URL. If these are independent services hosted by different parties, it would be strange to have a third-party publish one the "metadata" for them all, and potentially given them different/misleading names, or incompatible preFetchData from what the hook publisher intended.

I like the idea of 1:1 correspondence between the publisher of a hook and the publisher if its metadata, which option (1) above achieves. We could tweak your proposal by dropping the url, and then the concern would resolve.

Now, maybe we do want to describe a role for meta-aggregation here (e.g. here's the "list of hooks I like to use", which points to external services). But that would be a different structure, I think -- just a simple list of metadata endpoints, rather than repeating all the details.

view this post on Zulip Kalyani Yerra (Mar 21 2016 at 22:21):

Would it make sense to have different preFetch templates for different hooks.
For patient-view hook I may not need any preFetch data, but for medication-prescribe hook I might also need some Observation resources as my preFetch data.

view this post on Zulip Josh Mandel (Mar 21 2016 at 22:23):

Of course. That's part of Kevin's proposal.

view this post on Zulip Kalyani Yerra (Mar 21 2016 at 22:25):

Sorry missed that piece.

view this post on Zulip CDS Hooks Bot (Mar 22 2016 at 02:30):

kpshek commented on issue 10

But I'm not sure I understand the use case for giving each hook a separate URL.

My thinking here is that I wouldn't want to implement some super endpoint whose first order of business is to do a switch statement on the activity/name (eg, patient-view, medication-prescribe) and delegate to the appropriate logic. If by some chance your patient-view and medication-prescribe services were nearly identical, you could simply give them the same URL if you really wanted. However, even in this case I'd still prefer them to have different URLs so that I can track metrics on each without examining the request.

If these are independent services hosted by different parties, it would be strange to have a third-party publish the "metadata" for them all, and potentially give them different/misleading names, or incompatible preFetchData from what the hook publisher intended.
I like the idea of 1:1 correspondence between the publisher of a hook and the publisher of its metadata, which option (1) above achieves. We could tweak your proposal by dropping the url, and then the concern would resolve.

You lost me here. I was assuming that the creator and company hosting a CDS Service would also host their metadata endpoint for their service so I agree with you on the 1:1 correspondence. Where did this idea of a third-party CDS Service aggregator come from?

view this post on Zulip CDS Hooks Bot (Mar 22 2016 at 02:54):

jmandel commented on issue 10

Top level question: If you agree that it's a good practice to keep the services separate, why not keep the Metadata separate top?

As for the aggregation issue: it's more a fear than an idea. Since there's no constraint, and "url" can be anything, an EHR consuming Metadata can get tricked/confused by a third party that badly tries to point to other service. Whereas if we adopted a stronger convention, this would be impossible.

view this post on Zulip CDS Hooks Bot (Mar 22 2016 at 03:00):

jmandel commented on issue 10

And never mind my "aggregation" use case: I was just trying to anticipate one (apparently non-)reason why you might have wanted to define multiple Hooks in the same Metadata file.

view this post on Zulip CDS Hooks Bot (Mar 22 2016 at 03:18):

kpshek commented on issue 10

Top level question: If you agree that it's a good practice to keep the services separate, why not keep the Metadata separate too?

By separate, do you mean have a metadata endpoint for each service? If so, what I'd really love (more discussion here) is:

- metadata: GET /:hook
- service: POST /:hook/:id

Eg:
- GET https://cds-provider/patient-view to read the metadata resource for this service
- POST https://cds-provider/patient-view/0aaafead-3788-4733-a0e8-6221b76cb477 to invoke an instance of this service

But, we're going with FHIR API conventions (Parameters, operations, etc) so I took that off the table mentally and am going with the $ operation syntax. And, given that this doesn't resembles a RESTful API in this model, I don't know how to model what I want above in these constraints.

You have a lot more experience with FHIR modeling conventions than myself so if there is a way so if there is a better way, I'd love to know.

Since there's no constraint, and "url" can be anything, an EHR consuming Metadata can get tricked/confused by a third party that badly tries to point to other services. Whereas if we adopted a stronger convention, this would be impossible.

I'm all for establishing stronger conventions; I want this too and would prefer if CDS Providers weren't allowed to specify arbitrary URLs. This is another thing I like above the URI design that I would love -- CDS Providers just need to register their base URL with the EHR / registry.

I get why you've got the service defined at that master endpoint. Using the FHIR operations framework doesn't provide much flexibility (in the current FHIR spec). You'd have to define something like $cds-service-patient-view, $cds-service-medication-prescribe, etc. I'll reiterate that I think it's important that these services are offered at distinct URIs -- not just for the maintainability/clarity of the service code but also for monitoring, metrics, and independent scalability that distinct URIs would offer.

view this post on Zulip Josh Mandel (Mar 22 2016 at 10:53):

Kevin, I think we're talking past one another here. You say you want services offered at "distinct URLs" and I agree. I think the way to accomplish this "in FHIR" is by having CDS providers host different base URLs, like:

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 10:53):

After my last comment last night, I figured that's what you were thinking

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 10:54):

And yes, hosting services at different base URLs would work

view this post on Zulip Josh Mandel (Mar 22 2016 at 10:54):

https://cds-provider/my-med-service/$cds-hook
https://cds-provider/my-patient-service/$cds-hook
https://cds-provider/other-med-service/$cds-hook

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 10:54):

yep

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 10:54):

The downside to this is that the EHR has to register each of these separately

view this post on Zulip Josh Mandel (Mar 22 2016 at 10:54):

But that's my current (1)

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 10:55):

From my perspective (the EHR), I'd rather register a single base URL and then enable hooks on that base URL

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 10:57):

and when I said "then enable hooks on that base URL" I mean after registering the single base URL in the EHR, then my admin/config UI shows the individual services offered by each hook and I can just tick a box enabling the ones I want the EHR to call

view this post on Zulip Josh Mandel (Mar 22 2016 at 10:57):

So what if we took my (1) and added one more kind of document: a "hook manifested" that could live anywhere, and just contained a list of URLs (each a $cds-hook endpoint)

view this post on Zulip Grahame Grieve (Mar 22 2016 at 10:57):

yes that's what I do in my application (ah, what Kevin said)

view this post on Zulip Grahame Grieve (Mar 22 2016 at 10:58):

I think that there needs to be a single URL to point out that leads to the all the cds-hook types that the system supports.

view this post on Zulip Grahame Grieve (Mar 22 2016 at 10:58):

I think that it should be possible that that would be a FHIR conformance statement, even if the extent of that support is a reference to some other native expression of the cds hooks capabilities

view this post on Zulip Josh Mandel (Mar 22 2016 at 10:59):

I'm just wary about what is "the system" since it seems to limit to a single base url. The "manifest" would get around this.

view this post on Zulip Grahame Grieve (Mar 22 2016 at 11:00):

well, you should be able to have multiple hooks on single base url, yes?

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:00):

Josh: Well, I was thinking that if you wanted a separate base URL (for whatever reason), you could certainly do that (nothing precludes you from this today).

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:01):

Today there's no way to register a bunch of Hooks all at once though.

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:01):

Right

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:01):

And that's the problem you're aiming to solve.

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:01):

Yes

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:02):

And I agree with you that it would be good to have the URLs (other than base URL) be predictable.

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:02):

And I think we said that multiplex base URLs was the best way we knew to solve it

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:03):

As in:
https://cds-provider/my-med-service/$cds-hook
https://cds-provider/my-patient-service/$cds-hook
https://cds-provider/other-med-service/$cds-

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:03):

I said that I agreed that is one way to solve it

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:03):

Ah, ok.

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:03):

Do you have something you prefer?

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:05):

Yes, this: https://cds-provider/someBase/:hook/:id

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:06):

And I'd be fine using FHIR operations for this instead so:
https://cds-provider/someBase/:hook/$cds-hook

view this post on Zulip Grahame Grieve (Mar 22 2016 at 11:06):

what do you mean by :hook there?

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:06):

patient-view, medication-prescribe, etc

view this post on Zulip Grahame Grieve (Mar 22 2016 at 11:07):

ok, so isn't that naturally backwards? wouldn't $cds-hook/:hook be more natural?

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:07):

It depends

view this post on Zulip Grahame Grieve (Mar 22 2016 at 11:08):

what on?

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:08):

Do you want the metadata resource available on each hook invidually? If so, this makes more sense:
GET /:hook to retrieve the metadata
POST /:hook/$cds-hook to call the service

view this post on Zulip Grahame Grieve (Mar 22 2016 at 11:09):

heh I was about to write that

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:09):

If you want the metadata for all hooks on that base URL, this makes sense:
GET /$cds-hook to retrieve the metadata for all hooks
POST /$cds-hook/:hook to call the service

view this post on Zulip Grahame Grieve (Mar 22 2016 at 11:11):

if this was all FHIR directly, you would say that you had a resource that described the hook operation at [base]/CDSHook/:id, and you would invoke it at [base]/CDSHook/:id/$invoke of something. so a similar pattern. perhaps enough to be the same pattern

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:11):

Perhaps it would help if we listed out the goals we all agree upon here and then determine which options/designs achieve those goals

view this post on Zulip Grahame Grieve (Mar 22 2016 at 11:11):

GET [base]/CDSHook lists all the hooks...

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:11):

Do the only difference between what you wrote, Kevin, and what I wrote, is which piece of the URL in considered "the base".

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:11):

Agreed let's write goals.

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:12):

Goal *fhir": make sure that Hooks can be involved as fhir operations.

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:13):

Goal "bulk": make sure an EHR can register multiple Hooks with a single discovery point

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:13):

Yeah, I thought of that last night Grahame. If we created a new FHIR resource then a lot of this gets a bit easier

view this post on Zulip Grahame Grieve (Mar 22 2016 at 11:13):

I'm always game ;-)

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:14):

(But it wouldn't represent a resource, in anyone's sense. More like a reserved url path)

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:14):

Goal "distinct": make sure each hook is a distinct URL so that invocation can be metered, monitored, and scaled independently.

view this post on Zulip Grahame Grieve (Mar 22 2016 at 11:14):

the definition of what it does would be the resource

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:15):

Goal "predictable": make it easy to go from the url of a hook to the Metadata for it, without maintaining a bunch of state. Improved ease of use and security.

view this post on Zulip Grahame Grieve (Mar 22 2016 at 11:15):

Goal "introspection": there must be some way to discover what is avialable, what they do and how they work

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:16):

Anything else?

view this post on Zulip Grahame Grieve (Mar 22 2016 at 11:17):

well, how far do you want to go? do you want to talk about how it integrates into a wider context?

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:17):

Is the 'limit state' goal the same as predictable URLs (both to make it easy/uniform and for security)? If not, I’ll add that as another goal

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:18):

I'll change it to "predictable" and then yes.

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:18):

Cool

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:19):

Integration into a wider context: is this the "fhir" Goal or is it something more?

view this post on Zulip Grahame Grieve (Mar 22 2016 at 11:19):

I don't know whether you want this: I want to be able to host cds-hook calls under the fhir base for mgmt/security/provisioning reasons

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:19):

That's how I took the fhir goal above -- it should allow you to do that

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:20):

Agreed,Kevin.

view this post on Zulip Grahame Grieve (Mar 22 2016 at 11:20):

well, I was thinking about security - about the ability to have the cds-hook service be part of a wider service and share it's security

view this post on Zulip Grahame Grieve (Mar 22 2016 at 11:20):

I guess maybe. I'm thinking aloud

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:20):

Well, hopefully that's possible when we figure out the security bits :-)

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:21):

Clearly the "fhir" goal is these toughest constraint here. If we eliminated it, the others become easy.

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:22):

But leaving everything in place...

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:22):

Yes. Well, it's tough IMHO by keeping fhir as-is. If we were to make some changes to FHIR we can make this work

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:22):

One thing we could do is go *not* have consistently named operations

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:23):

https://cds-provider/$my-med-service/$cds-hook
https://cds-provider/$my-patient-service
https://cds-provider/$other-med-service

view this post on Zulip Grahame Grieve (Mar 22 2016 at 11:23):

we can consider changes

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:23):

And only standardize the name of the Metadata operation

view this post on Zulip Grahame Grieve (Mar 22 2016 at 11:23):

I'm not sure what you mean there

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:23):

Josh: those URLs you just posted don't serve our predictable goal

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:24):

Ah, they just provide a predictable way to get Metadata given a hook (strip the hook url, append "$cds-hooks-meta" or whatever

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:25):

Posting here so we have them all together:

Goal *fhir": make sure that Hooks can be involved as fhir operations.

Goal "bulk": make sure an EHR can register multiple Hooks with a single discovery point

Goal "distinct": make sure each hook is a distinct URL so that invocation can be metered, monitored, and scaled independently.

Goal "predictable": make it easy to go from the url of a hook to the Metadata for it, without maintaining a bunch of state. Improved ease of use and security.

Goal "introspection": there must be some way to discover what is avialable, what they do and how they work

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:25):

Grahame: I'm just saying we can define inputs and outputs but let servers host the operation at various names

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:25):

But they are not predictable in that if I have a baseURL, I know what hooks are offered off of that baseURL. Not without some super metadata document

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:26):

The Metadata document could live at a fixed url, always (relative to base)

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:26):

If we add a 5th type of FHIR endpoint that operations can hang of off (https://www.hl7.org/fhir/operations.html), this becomes doable I think

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:26):

Only the hook operation URLs would vary

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:27):

I like that, Kevin.

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:27):

Just "a reserved path segment" or some such.

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:27):

fyi - I have to drop off in 2 min for a 30min call

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:27):

Yes, exactly

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:27):

Once upon a time we said every path starting with "_" was fair game.

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:28):

I have to run too

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:28):

OR, we accept a single metadata endpoint off the base URL (this was in my #3 proposal on the GH issue) + predictable operation names (like $cds-hook-patient-view, $cds-hook-medication-prescribe).

But I really dont like this

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:28):

But (3) alone still doesn't let one server host multiple patient-view Hooks.

view this post on Zulip Grahame Grieve (Mar 22 2016 at 11:29):

how are these names controlled?

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:29):

Gotta run now -- I'll be online in a few hrs as after my call I've got to go into work (still at home atm)

view this post on Zulip Kevin Shekleton (Mar 22 2016 at 11:30):

Thanks both for the great discussion on this! I don't know about you two, but I'm having a lot of fun with all of this :-)

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:30):

They're part or an extensible catalog, so they re really not controlled (i.e. You can have private activities too)

view this post on Zulip Grahame Grieve (Mar 22 2016 at 11:30):

and how are they described?

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:31):

https://github.com/cds-hooks/cds-hooks/wiki/Activity

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:34):

Another solution is to stop trying to make expressive URLs and just add one more field to the hook inputs: "hook-id". A provider would publish as many Hooks as it wanted, all invoked at "/$cds-hooks", and the id from Kevin's proposal just becomes an input parameter.

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:35):

Nope - It breaks "distinct"

view this post on Zulip Grahame Grieve (Mar 22 2016 at 11:35):

does it?

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:35):

Absolutely

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:36):

Metering, mojotoring, and scaling independently by url

view this post on Zulip Grahame Grieve (Mar 22 2016 at 11:36):

how? because it's not in the URL?

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:37):

Right. API gateways and reverse proxy servers make this stuff easy if you have distinct URLs, and hard if you don't.

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:38):

Realty were should extend the FHIR operations framework as follows:

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:38):

Any non-complex parameter can be pasted in through a url path.

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:40):

Maybe the best way to standardize it is by a convention like "$operation/:name/:value/:name2/:value2"

view this post on Zulip Grahame Grieve (Mar 22 2016 at 11:40):

that's really yuck

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:41):

How about if your operation includes a list of "path parameters"?

view this post on Zulip Grahame Grieve (Mar 22 2016 at 11:41):

they can come in an order? why do we invent a syntax that's different from how they should be done?

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:41):

And that list is ordered

view this post on Zulip Grahame Grieve (Mar 22 2016 at 11:41):

well, one or two, maybe. differntiating parameters? I'd be interested in an analysis of our existing operations and where that technique might lead to goodness

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:42):

So then the hook operation defined a single path parameter called "hook-id"

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:42):

Type, string

view this post on Zulip Grahame Grieve (Mar 22 2016 at 11:42):

I can to the analysis myself tomorrow but not now

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:42):

And then invocation is just "POST $cds-hook/price-check"

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:54):

But this all still would make Hooks unusable from current libraries (e.g. hapi) . That may violate the "fhir" goal.

view this post on Zulip Grahame Grieve (Mar 22 2016 at 11:58):

why would it make them unusable? the libraries would need to enhance to know about this new thing we're talking about

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:58):

By "current", I mean literally today

view this post on Zulip Josh Mandel (Mar 22 2016 at 11:59):

Er, current

view this post on Zulip Grahame Grieve (Mar 22 2016 at 11:59):

yes correct

view this post on Zulip Josh Mandel (Mar 22 2016 at 21:25):

So in terms of where we'd like to go: yes, extended operations (to take some path parameters -- even just one) would help. @Grahame Grieve I'll look forward to the analysis (let me know what I can do to help on that).

view this post on Zulip Josh Mandel (Mar 22 2016 at 21:42):

In terms of what we can do right now (DSTU2 compatible) and meets our goals, the best I can come up with is:

1. Independent CDS services live at /$cds-hook. Technically you can host >1 service at a single endpoint, if they each handle a different "activity". And service provides can make as many "base URLs" as they need to keep services separate.

(To satisfy "distinct")

2. Each service is associated with its own metadata by appending -metadata to the hook URL. This is a document with at most one hook per activity, and looks like (after Parameters tax):

{
  "hook": [{
    "activity": "patient-view",
    "description": "Show a patient's name",
    "name": "Patient Namer"
  }, {
    "activity": "medication-prescribe",
    "description": "Show cost of a prescription",
    "name": "Rx Cost"
  }]
}

(To satisfy "predictable")

3. CDS service provider should publish a "Hook Set" (i.e. a single entry point for discovery) at any URL (not necessarily even a FHIR server). The Hook Set is a JSON document like:

[
  "https://service-vendor.example.org/med-price-hook/$cds-hook",
  "https://service-vendor.example.org/med-genomics-hook/$cds-hook",
  "https://service-vendor.example.org/patient-greeting-hook/$cds-hook"
]

(To satisfy "bulk")

4. A CDS services that happens to be a FHIR server can also include a link to its "Hook Set" specification by adding an extension to its conformance statement:

{
  "extension": [{
    "url": "http://cds-hooks.org/hook-set-url",
    "valueUrl": "https://service-vendor.example.org/hook-set.json"
  }]
}

(To satisfy "introspection")

view this post on Zulip Grahame Grieve (Mar 22 2016 at 21:44):

how important is it to be DSTU2 compatible?

view this post on Zulip Josh Mandel (Mar 22 2016 at 21:44):

Feels important to me (it's part of what I mean by "fhir").

view this post on Zulip Grahame Grieve (Mar 22 2016 at 21:45):

well, that would need to be explicitly stated. I'm not sure, myself. Adding API features and then getting them retrospectively adopted is different to modifying resource structures and getting them retrospectively adopted

view this post on Zulip Josh Mandel (Mar 22 2016 at 21:46):

Different in which direction (easier or harder, do you mean)?

view this post on Zulip Josh Mandel (Mar 22 2016 at 21:46):

In the above, I'm proposing neither (no API features and no different resource structures).

view this post on Zulip Josh Mandel (Mar 22 2016 at 21:47):

The thing is, if we don't care about DSTU2 I'm not convinced we should care about the rest of the "fhir" objective (I mean, we'd be speculating on what we can get incorporated through the standards process.)

view this post on Zulip Grahame Grieve (Mar 22 2016 at 21:47):

easier. I know you're not proposing either. But is the consequence of that being backwards compatible means a less than ideal design? is that a good value decision going forward? I'm just asking

view this post on Zulip Grahame Grieve (Mar 22 2016 at 21:48):

I see those as different things, but yes, the speculation part is potentially problematic

view this post on Zulip Josh Mandel (Mar 22 2016 at 21:49):

What I mean is, the really awkward position would be to design something not quite as clean ad we'd like (as a compromise for STU3 acceptability) and then still not have our design requirements incorporated into STU3.

view this post on Zulip Grahame Grieve (Mar 22 2016 at 21:50):

yeah, that would be less than ideal

view this post on Zulip Grahame Grieve (Mar 22 2016 at 22:06):

This is a list of possibly useful places in the existing operations :
ConceptMap.$closure: name
DecisionSupportRule.$evaluate: requestId?
List.$find: name
Measure.$evaluate: reportType?
MessageHeader.$process : async?

view this post on Zulip Grahame Grieve (Mar 22 2016 at 22:06):

The list is short mainly because most operations have their own resource to be associated with anyway

view this post on Zulip Grahame Grieve (Mar 22 2016 at 22:07):

and I think that would make a difference here. If each cds-hook operation had a resource that defined it's operation, then that would have a solid URL:

view this post on Zulip Grahame Grieve (Mar 22 2016 at 22:07):

GET [base]/CDSHookDefinition/[name]

view this post on Zulip Grahame Grieve (Mar 22 2016 at 22:08):

where name would be for each instance of a hook operation (not type - that would be a property in the return). Of course, I'm implying the FHIR approach there, but I think the logic would apply anyway

view this post on Zulip Grahame Grieve (Mar 22 2016 at 22:08):

and then to exceute it:

view this post on Zulip Grahame Grieve (Mar 22 2016 at 22:08):

GET [base]/CDSHookDefinition/[name]/$evaluate

view this post on Zulip Grahame Grieve (Mar 22 2016 at 22:09):

maybe the parameters in path thing is still useful here....

view this post on Zulip Josh Mandel (Mar 22 2016 at 22:19):

What's an example of "[name]" here? Is it like "rx-cost-calculator" (i.e. an ad-hoc, URL slug-formatted descriptor)?

view this post on Zulip Josh Mandel (Mar 22 2016 at 22:19):

How is:

POST [base]/CDSHookDefinition/rx-cost

better/different than:

POST [base]/$cds-hook/rx-cost?

view this post on Zulip Grahame Grieve (Mar 22 2016 at 22:20):

POST [base]/CDSHookDefinition/rx-cost/$evaluate

view this post on Zulip Grahame Grieve (Mar 22 2016 at 22:21):

that's not much different. The difference is that because you treat the definition as a normal resource, then you get search, pub/sub, etc out of the box for the definitions (at least, out of the box from FHIR anyway, but the principle holds)

view this post on Zulip Josh Mandel (Mar 22 2016 at 22:22):

What is the definition, though? The metadata?

view this post on Zulip Josh Mandel (Mar 22 2016 at 22:22):

And then rx-cost is an instance id?

view this post on Zulip Grahame Grieve (Mar 22 2016 at 22:23):

yes. that's an instance of a cdshooks service - specifically, a resource that describes the service and how you use it

view this post on Zulip Josh Mandel (Mar 22 2016 at 22:24):

That's interesting. Didn't you just say that defining a new retrospective resource was harder than defining a new retrospective API feature? (Or did I get the direction wrong?)

view this post on Zulip Grahame Grieve (Mar 22 2016 at 22:36):

changing one is what is worst of all but yes, defining a new one would be very difficult to retrospectively adopt. But if we - say - said that was a direction we wanted to go (would make it easy to publish cds hook definitions in implementation guides, registries etc), then it would guide us towards how to retrospectively fitted it to dstu2

view this post on Zulip Josh Mandel (Mar 22 2016 at 22:39):

Anyway, hook-definition-as-resource is a fascinating idea. Thanks for that :-)

view this post on Zulip Grahame Grieve (Mar 22 2016 at 22:40):

well, you've kind of already defined it. might as well go the whole hog....

view this post on Zulip Josh Mandel (Mar 22 2016 at 22:52):

Well, whole hog requires defining inputs and outputs too. But just don't see using FHIR's official international resource Balloting process for something like this.

view this post on Zulip Josh Mandel (Mar 22 2016 at 22:53):

We want the level of convenience of having a resource , but the process is not a fit. The "80%" methodology wouldn't even seem relevant.

view this post on Zulip Grahame Grieve (Mar 22 2016 at 22:53):

why not? you don't want people to use it?

view this post on Zulip Josh Mandel (Mar 22 2016 at 22:53):

Of course we want people to use it.

view this post on Zulip Grahame Grieve (Mar 22 2016 at 22:53):

and also, why not? because it's new and the entire scope of implementers are all new ?

view this post on Zulip Josh Mandel (Mar 22 2016 at 22:54):

But it's not a healthcare resource. Yes, and all new scope

view this post on Zulip Grahame Grieve (Mar 22 2016 at 22:54):

then everyone agrees, and 80% = 100%

view this post on Zulip Grahame Grieve (Mar 22 2016 at 22:54):

not a healthcare resource? don't understand.

view this post on Zulip Josh Mandel (Mar 22 2016 at 22:54):

There are hundreds of ideas that deserve equal footing m

view this post on Zulip Grahame Grieve (Mar 22 2016 at 22:55):

it's fine to prototype something in the wild, informally. but once people start committing to it, then you start needed a heavier weight process.

view this post on Zulip Josh Mandel (Mar 22 2016 at 22:55):

Are you saying they should all be balllted in FHIR?

view this post on Zulip Grahame Grieve (Mar 22 2016 at 22:55):

what?

view this post on Zulip Josh Mandel (Mar 22 2016 at 22:56):

Especially the inputs and outputs, it just feels like they're not "resources" in FHIR's sense. I want to have a nice format for inputs to an hook, but it doesn't make sense to do CRUD on that input (or especially on the output)

view this post on Zulip Grahame Grieve (Mar 22 2016 at 22:58):

umm I think we were talking at cross purposes. what you have now is an agreed single format for defining a specific operation, and how it describes what the inputs and outputs are, and a framework for doing the inputs and outputs

view this post on Zulip Grahame Grieve (Mar 22 2016 at 22:58):

I'm not proposing any change to that. Just making the single format a resource

view this post on Zulip Josh Mandel (Mar 22 2016 at 22:59):

What if our preferred heavier process isn't an HL7 Balloting modeling though? What if it's a committer model?

view this post on Zulip Josh Mandel (Mar 22 2016 at 23:01):

It feels like FHIR is configured consume any vaguely related projects into its gravity well if the only way to build clean stuff on top is to assimilate into the ballot process.

view this post on Zulip Josh Mandel (Mar 22 2016 at 23:02):

Anyway, which of Metadata vs inputs vs outputs should be a resource : that is a separate issue

view this post on Zulip Grahame Grieve (Mar 22 2016 at 23:03):

I think that's wishful thinking. As you start out, that works really well. You cycle quickly, you're responsive. The community is tight-knit. It's all good. But over time, the community spreads, existing committers that are heavily invested move onto other things, then change process gets harder, more money is committed, execs start asking how their investment is protected, government start wanting to specify things....

view this post on Zulip Grahame Grieve (Mar 22 2016 at 23:03):

there's a reason for the standards process

view this post on Zulip Josh Mandel (Mar 22 2016 at 23:04):

I don't dispute any of that. It's all good! But it can't be the solution to every problem.

view this post on Zulip Josh Mandel (Mar 22 2016 at 23:04):

Anyway, we're far afield in this discussion :p

view this post on Zulip Grahame Grieve (Mar 22 2016 at 23:04):

well. it depends how much use you have. But the question of integration into fhir itself... that's something we need to work on more, agree

view this post on Zulip Bryn Rhodes (Mar 22 2016 at 23:34):

So, I'm trying to get caught up on this thread, but there's a lot here, so I apologize if I'm rehashing ground you've already covered, but it sounds like what Grahame is suggesting is fairly close to the approach that we've taken in CQIF. We consider a CDS Service as composed of Modules, each of which has a different signature.

view this post on Zulip Bryn Rhodes (Mar 22 2016 at 23:34):

From the perspective of the caller, the "module" is a black box. It's a service definition that has inputs and outputs.

view this post on Zulip Bryn Rhodes (Mar 22 2016 at 23:35):

As far as it not being a "health care resource", I see what you mean, and I sort of agree, but then, neither is StructureDefinition, or Questionnaire.

view this post on Zulip Bryn Rhodes (Mar 22 2016 at 23:35):

And treating them as Resources in the FHIR sense allows us to use the existing FHIR functionality. Why can't you use basic CRUD against service definitions? Registering a service then becomes a POST to the DecisionSupportServiceModule resource.

view this post on Zulip Bryn Rhodes (Mar 22 2016 at 23:35):

Querying for what services are supported is just a GET.

view this post on Zulip Bryn Rhodes (Mar 22 2016 at 23:37):

It also already supports the notion of "required data", what CDS-Hooks calls "pre-fetch templates".

view this post on Zulip Bryn Rhodes (Mar 22 2016 at 23:38):

And the "activity" definitions are supported as "named events".

view this post on Zulip Bryn Rhodes (Mar 22 2016 at 23:39):

I'm sure it's not a perfect fit, but there's a lot there that can be leveraged.

view this post on Zulip Josh Mandel (Mar 23 2016 at 00:17):

As for"using CRUD", my point here was if we defined a "CDSHooksInput" and "CDSHooksOutput" resource (or similar), these would make little/no sense for CRUD. And overall this just feels like a square peg in a round hole to me.

Yes, CRUD feels fine for the metadata/descriptions.

view this post on Zulip Bryn Rhodes (Mar 23 2016 at 00:19):

I see, I missed that. Yes, I agree with that.

view this post on Zulip Grahame Grieve (Mar 23 2016 at 00:33):

you know, if we said that the metadata/descriptions was a custom resource, and the RI and servers got around to supporting custom resources, then you'd have a path that maintained publishing/life cycle independence, but made ready to become part of FHIR (e.g. balloting) when the time is right

view this post on Zulip Josh Mandel (Mar 23 2016 at 00:35):

Well yes. That's very true -- that's the kind of de-coupling I'm talking about (and indeed, inputs/outputs could be custom resources too, to avoid "parameters")

view this post on Zulip Grahame Grieve (Mar 23 2016 at 00:36):

I've never liked inputs and outputs being resources. That'll lead to 1000s of resources, and who'll know how to support them?

view this post on Zulip Bryn Rhodes (Mar 23 2016 at 00:37):

And by custom resources here, you mean the ability to define what looks and feels like a first-class resource but that isn't part of the core FHIR spec, right? (Just making sure you don't mean a profile of Basic with extensions)

view this post on Zulip Grahame Grieve (Mar 23 2016 at 00:37):

I'm trying to find time to do policy stuff like this, but I'm flat stick trying to get the freeze ready

view this post on Zulip Grahame Grieve (Mar 23 2016 at 00:37):

Bryn yes

view this post on Zulip Josh Mandel (Mar 23 2016 at 00:38):

If I can just point my FHIR client at the "CDS Hooks Resource Pack v 0.4.1" and write code against it... then who needs to "know how to support them"? You'd just read the docs for CDS Hooks and you'd be good.

view this post on Zulip Bryn Rhodes (Mar 23 2016 at 00:38):

Agree on Inputs and Outputs not being resources, APIs that do this (define structures for everything) are very unwieldy, IMHO.

view this post on Zulip Josh Mandel (Mar 23 2016 at 00:38):

Wait, every API defines inputs and outputs.

view this post on Zulip Josh Mandel (Mar 23 2016 at 00:39):

We might be talking past each other if you're thinking of something "unwieldy".

view this post on Zulip Bryn Rhodes (Mar 23 2016 at 00:39):

Yes but most do it with parameters.

view this post on Zulip Bryn Rhodes (Mar 23 2016 at 00:39):

Yes, maybe.

view this post on Zulip Grahame Grieve (Mar 23 2016 at 00:39):

well, that's fine for someone who writes bespoke APIs to support a few options. But as you scale that up, people get desparate for continuity across the engineering framework

view this post on Zulip Bryn Rhodes (Mar 23 2016 at 00:40):

I'm thinking of APIs that define Structs for everything, even if the call only has one or two parameters.

view this post on Zulip Grahame Grieve (Mar 23 2016 at 00:40):

so you get some kind of double layer. Which is how I proposed to use the Parameters resource

view this post on Zulip Bryn Rhodes (Mar 23 2016 at 00:41):

Agreed, that's actually why we opted for defining a specific resource for DecisionSupportServiceModule, rather than making it a profile of OperationDefinition.

view this post on Zulip Grahame Grieve (Mar 23 2016 at 00:41):

don't see the connection

view this post on Zulip Bryn Rhodes (Mar 23 2016 at 00:41):

Because we think there are a handful of parameters that every service will need, so we define those on the $evaluate operation itself.

view this post on Zulip Josh Mandel (Mar 23 2016 at 00:41):

@Bryn Rhodes gotcha -- this isn't what I mean. I just mean I'd rather pass:

{
"a":  1
}

than

{
  "resourceType": "Parameters",
  "parameters": [{"name": "a", "valueInteger": 1}]
}

view this post on Zulip Brian Postlethwaite (Mar 23 2016 at 09:08):

I'm also a little late to the conversation, but from my perspective its sounding kind of like what cds-hook is doing is very similar to what VBA macros were doing years ago.
Apps had defined injection points that you cook hook code into that could do things.
These had parameters you could process and do what you liked, and actions you could take on things.
This then turned into apps that were built onto the models for each application.
(Not saying that we should adopt anything from it, just that we could learn from others experiences)

view this post on Zulip Brian Postlethwaite (Mar 23 2016 at 09:16):

My preference is to keep the hook metadata seperate rather than a complete set, and I would like it to be a complete resource that can be udpated (enabled/disabled) as desired, and would then have the execution of the hook via a $evaluate (or $execute) after the hook resource name

view this post on Zulip Brian Postlethwaite (Mar 23 2016 at 09:17):

Would also like to be able to search through services also, especially if there end up being lots of them

view this post on Zulip Bryn Rhodes (Mar 23 2016 at 14:44):

https://hl7-fhir.github.io/decisionsupportservicemodule.html

view this post on Zulip Bryn Rhodes (Mar 23 2016 at 14:44):

This is the resource I'm thinking of as a fit for the metadata/description of the CDS-hooks services.

view this post on Zulip David Hay (Mar 24 2016 at 07:45):

afaik the prefetch templates are different for each hook...


Last updated: Apr 12 2022 at 19:14 UTC