FHIR Chat · Versioned API Connectathon Track · implementers

Stream: implementers

Topic: Versioned API Connectathon Track


view this post on Zulip Grahame Grieve (Dec 23 2017 at 22:44):

This track hasn't got any registered participants, though discussions about this at WGMs are always passionate. So this is a ping to prompt people - who's interested?

view this post on Zulip Grahame Grieve (Dec 23 2017 at 22:44):

btw, my server does scenarios 1 and 2 right now, but not 3 or 4

view this post on Zulip Abbie Watson (Dec 27 2017 at 02:07):

Versioning like how Aegis/Touchstone recommends? Within the URL?

view this post on Zulip Joel Schneider (Dec 27 2017 at 02:10):

Presumably, 1, 2, 3, and 4 are references to this:
http://wiki.hl7.org/index.php?title=201801_Versioned_API

view this post on Zulip Abbie Watson (Dec 27 2017 at 02:26):

Presumably, 1, 2, 3, and 4 are references to this:
http://wiki.hl7.org/index.php?title=201801_Versioned_API

So, according to this:
https://www.hl7.org/fhir/directory.html

We're talking about long term support for v0.0.82, v1.0.2, and v3.0.1?

I ask because we've implemented most of our stack on v1.6.0 and v3.0.1. We're in a position to do testing between r2 and r3, and would like to formalize our r2 spec to conform with Epic2015. But we'd like to be specific about whether to peg to v1.0.2 or v1.6.0. Downgrading to v1.0.2 is fine if it means clarity and alignment with Epic2015.

view this post on Zulip Christiaan Knaap (Dec 27 2017 at 07:32):

I'm interested in the topic, but can't make Vonk support multiple versions before the Connectathon. So while I could probably make it support scenario's 1&2, I doubt it is useful when supporting only R3.

view this post on Zulip Grahame Grieve (Dec 27 2017 at 09:34):

1.6.0 isn't on the list of supported releases; the Java reference implementation supports it, but that's the only one. And I'm not sure how long it will - it's existence continues to cost.

view this post on Zulip Grahame Grieve (Dec 27 2017 at 09:34):

I only support scenarios 1 and 2 at present; I have't decided about 3

view this post on Zulip Peter Jordan (Dec 27 2017 at 21:33):

Will support scenario 2 - scenarios 1 and 3 won't be applicable until/unless there are any breaking changes to the Terminology Module in R4.

view this post on Zulip Grahame Grieve (Dec 27 2017 at 21:39):

code system supplements are new in R4

view this post on Zulip Peter Jordan (Dec 27 2017 at 22:07):

Should have qualified that with "my current implementation"! Certainly true that returning supplements (and content=content-mode.supplement) might break an R3 client. I'll create a test CodeSystem resource on my server that implements this for the Connectathon.

view this post on Zulip Kevin Olbrich (Jan 02 2018 at 19:21):

@Grahame Grieve I'm interested in this track. I think there is also another variant of scenario 1, where the client sends an 'Accept' header with a value like 'json+fhir; fhirVersion=1.6.0' and then using content type negotiation to figure out what to return.

view this post on Zulip Grahame Grieve (Jan 02 2018 at 19:47):

well, we're trying to not support 1.6.0 anymore - my server won't, that's for sure

view this post on Zulip Kevin Olbrich (Jan 02 2018 at 19:59):

The idea was to put an explicit, semantic version number in the header. It could be Accept: application/fhir+json; fhirVersion=3.0.1, application/json+fhir; fhirVersion=1.0.2 and then the server would respond with a Content-Type: application/json+fhir; fhirVersion=1.0.2 and the proper payload if it couldn't handle the 3.0.1 version.

view this post on Zulip Grahame Grieve (Jan 02 2018 at 20:33):

we certainly don't want the revision number in the version

view this post on Zulip Grahame Grieve (Jan 02 2018 at 20:33):

3.0.0 and 3.0.1 and 3.0.x are all compatible

view this post on Zulip Grahame Grieve (Jan 02 2018 at 20:34):

that's why the connectathon write up specifies r2 / r3 / r4 instead of the semver version

view this post on Zulip Grahame Grieve (Jan 02 2018 at 20:34):

and on the negotiation... I think most people would prefer and error than stuff from the wrong version

view this post on Zulip Kevin Olbrich (Jan 02 2018 at 20:48):

I'm ok with just doing 1.0, or 3.0 without the patch version since the differences are so minor, I just prefer to be explicit and the official release version has a patch level number in it. Regarding the negotiation, you would only pass versions you can handle in the Accept header. The server would pick the first one in the list that it can handle and return that one. The client would then determine which one to use based on the Content-Type header that is returned. You would never get the wrong version because you told the server which ones you want. Of course if the server didn't handle any of the versions, that would return an error.

view this post on Zulip Grahame Grieve (Jan 02 2018 at 20:51):

so ok, that's just content negotiation as envisaged in the connectathon write up

view this post on Zulip Kevin Olbrich (Jan 02 2018 at 20:57):

Yes, similar to scenario 1 with some minor differences from what I saw. The wiki page specified a custom header, but I don't think we need a custom header. I found this article helpful when we were trying to sort this out in our systems... https://www.troyhunt.com/your-api-versioning-is-wrong-which-is/

view this post on Zulip Grahame Grieve (Jan 02 2018 at 21:01):

wiki specifies a content type parameter

view this post on Zulip Kevin Olbrich (Jan 02 2018 at 21:22):

Ah, I see. The wording in the writeup confused me a little. We are, in fact, violently agreeing about scenario 1.

view this post on Zulip Grahame Grieve (Jan 02 2018 at 21:22):

except for r3 vs 3.0

view this post on Zulip Kevin Olbrich (Jan 02 2018 at 21:25):

Yes. Personally I think there should be one and only one way of specifying a particular version of the standard.

view this post on Zulip Grahame Grieve (Jan 02 2018 at 21:31):

unfortunately we'll never get to that point because of external constraints. Though we at least have r3 = 3.0 now

view this post on Zulip Grahame Grieve (Jan 02 2018 at 21:34):

feel free to add clarifying text to the wiki btw

view this post on Zulip Kevin Olbrich (Jan 02 2018 at 21:52):

Why did you call the version r3 instead of just 3 or 3.0?

view this post on Zulip Grahame Grieve (Jan 02 2018 at 22:05):

that's the official product name now

view this post on Zulip Grahame Grieve (Jan 09 2018 at 02:17):

C17_Versioned_API.pptx

view this post on Zulip Grahame Grieve (Jan 09 2018 at 02:17):

FYI

view this post on Zulip Grahame Grieve (Jan 20 2018 at 20:09):

I have upgraded test.fhir.org to better support the versioned API track.

view this post on Zulip Grahame Grieve (Jan 20 2018 at 20:10):

test.fhir.org runs 3 end-points:

view this post on Zulip Grahame Grieve (Jan 20 2018 at 20:11):

each has it's own set if resources, starting with the example resources defined in the relevant version of the spec, and then diverging based on whatever people have posted since I installed the test set.

view this post on Zulip Grahame Grieve (Jan 20 2018 at 20:11):

When you specify the Accept and Content-Type headers, by default the version is the base version for the end-point. But now, you can also do this:

view this post on Zulip Grahame Grieve (Jan 20 2018 at 20:12):

GET http://test.fhir.org/r3/Patient/example
Accept: application/fhir+xml; fhir-version=r4

view this post on Zulip Grahame Grieve (Jan 20 2018 at 20:12):

and you'll get the r3 patient resource converted to r4

view this post on Zulip Grahame Grieve (Jan 20 2018 at 20:13):

The conversion is performed by the Java version conversion code in the Java reference implementation

view this post on Zulip Grahame Grieve (Jan 20 2018 at 20:14):

It's important to note: test.fhir.org will convert between versions of the resource, but it will not (and cannot, given the architecture) support search parameters from a different version than the specified end-point

view this post on Zulip Kevin Olbrich (Jan 20 2018 at 21:35):

@Grahame Grieve is it possible to make requests like

GET http://test.fhir.org/Patient/example

to get the latest version?

view this post on Zulip Grahame Grieve (Jan 20 2018 at 21:39):

it would be possible for me to configure the server like that, yes. it would be exactly the same as /r4/Patient/example - what would be the benefit?

view this post on Zulip Kevin Olbrich (Jan 20 2018 at 21:51):

If I record the canonical URL for a resource in a system, I can always go back and get it without having to know or care what version it was at the time I saved it. I would prefer to use the versionless url (because it represents the resource) and then specify which version I wanted in the Accept header. This is easier for server operators. If a client has stored a url of 'http://test.fhir.org/r2/Patient/example' then I will have to honor that URL forever or clients won't be able to reliably find the resource when they need it. If they store 'http://test.fhir.org/Patient/example' then they will always be able to get the resource, but they might run into trouble if they don't know how to handle the latest version.

view this post on Zulip Grahame Grieve (Jan 20 2018 at 21:55):

I think this is moving the deck chairs around. It's painful one way or the other. For the test server, in particular, where the R4 end-point is a rolling one, I think it's better not to try and offer that.

view this post on Zulip Kevin Olbrich (Jan 20 2018 at 22:08):

In what way is the versionless-url variety painful? A client can always make a request like

GET http://test.fhir.org/Patient/example
Accept: application/fhir+json; fhir-version=r2

and they will most likely get a reasonable response, even years from now.
If clients store the URL as 'http://test.fhir.org/r2/Patient/example' then we are forever required to maintain that URL because some client will expect it to be there. Also it makes it harder for clients to recognize when records are identical. 'http://test.fhir.org/r2/Patient/example' points to the record for the same patient as 'http://test.fhir.org/r3/Patient/example', but the URLs are not the same. If we go that route we might as well do something like 'http://test.fhir.org/r3/xml/Patient/example' (which would perpetually tie the client to the serialization format AND the fhir-version).
(see https://www.troyhunt.com/your-api-versioning-is-wrong-which-is/ for some discussion of this).

view this post on Zulip Grahame Grieve (Jan 20 2018 at 22:10):

so I am not sure whether you are specifically asking about my choices for test.fhir.org, or making a general policy point.

view this post on Zulip Grahame Grieve (Jan 20 2018 at 22:11):

my choices for test.fhir.org are not the same as 'these are the rules for everyone'.

view this post on Zulip Grahame Grieve (Jan 20 2018 at 22:11):

having said that, I personally don't see any difference between support R2 by header or by end-point for the read operation. But there's a big difference for search

view this post on Zulip Grahame Grieve (Jan 20 2018 at 22:12):

I agree that there is some benefit for version-less URLs... just as there is a cost. My choice not to provide that on test.fhir.org (for now) does not mean that no one else should make that choice

view this post on Zulip Kevin Olbrich (Jan 20 2018 at 22:32):

I was more making a point about the general policy than your specific choices for the test servers.

view this post on Zulip Grahame Grieve (Jan 20 2018 at 22:37):

well, it's something people can choose to do, if the connectathon test track goes ok

view this post on Zulip Bradley Strecker (Jan 27 2018 at 15:53):

Cerner staging test url: https://fhir-open.stagingcerner.com/stu3/fb8067d7-e012-4703-8888-17b86d11f0f8/

view this post on Zulip Grahame Grieve (Jan 27 2018 at 15:58):

@Bradley Strecker : why list 'r3' and '3.0'?

view this post on Zulip Grahame Grieve (Jan 27 2018 at 15:59):

also, when the mime type is application/fhir+json, you should return - as you do:

{
    "resourceType": "Parameters",
    "parameter": [
        {
            "name": "fhir-version",
            "valueString": "r3"
        },
        {
            "name": "fhir-version",
            "valueString": "3.0"
        }
    ]
}

view this post on Zulip Grahame Grieve (Jan 27 2018 at 16:00):

but when the accept type is application/json, the return should be

view this post on Zulip Grahame Grieve (Jan 27 2018 at 16:00):

{
   "versions": ["r3", "3.0"]
 }

view this post on Zulip Bradley Strecker (Jan 27 2018 at 16:02):

@Grahame Grieve Yeah, that was listed as "bonus points" and I didn't get to it, planned on working on that today. As for listing r3 and 3.0, thats from the track description: "where X is the formal release (r2,r3, or r4 for the current build at this time) (alternately X could be a semantic version number 1.0, 1.6 or 3.0"

view this post on Zulip Grahame Grieve (Jan 27 2018 at 16:05):

ok. thx. so we need to decide whether it's going to be "r3' or "3.0". but the real comment was - I expected you to list r2 and r3

view this post on Zulip Ioana Singureanu (Jan 27 2018 at 16:06):

The servers use "3.0.x' - for simplicity we should use that. This way the clients don't get confused.

ok. thx. so we need to decide whether it's going to be "r3' or "3.0". but the real comment was - I expected you to list r2 and r3

view this post on Zulip Grahame Grieve (Jan 27 2018 at 16:07):

no we should not use the revision - technical corrections cause a change to the revision number but we definitely don't want those to be relevant here

view this post on Zulip Bradley Strecker (Jan 27 2018 at 16:09):

@Grahame Grieve - We have separate servers for each version and won't be supporting on the fly conversions any time in the near future. I can add r2 for connectathon testing purposes, but you'll still only be able to get r3 resources

view this post on Zulip Grahame Grieve (Jan 27 2018 at 16:10):

ok; understand. well, the, what's a resource I can fetch on that server? a patient?

view this post on Zulip Bradley Strecker (Jan 27 2018 at 16:12):

Any of the resources listed in the metadata should return r3 resources. Give me a sec and I'll dig up a test patient with encounters

view this post on Zulip Grahame Grieve (Jan 27 2018 at 16:13):

thx

view this post on Zulip Grahame Grieve (Jan 27 2018 at 16:15):

yay:

GET https://fhir-open.stagingcerner.com/stu3/fb8067d7-e012-4703-8888-17b86d11f0f8/Patient/1153923
Accept: application/fhir+json; fhir-version=r4

view this post on Zulip Grahame Grieve (Jan 27 2018 at 16:16):

The Accept fhir-version is invalid. It must be one of: r3, 3.0

view this post on Zulip Grahame Grieve (Jan 27 2018 at 16:16):

It would be better if this was an OperationOutcome

view this post on Zulip Bradley Strecker (Jan 27 2018 at 16:23):

@Grahame Grieve https://fhir-open.stagingcerner.com/stu3/fb8067d7-e012-4703-8888-17b86d11f0f8/Encounter?patient=4330902

view this post on Zulip Chris Grenz (Jan 27 2018 at 17:02):

Conversion java code: https://gforge.hl7.org/gf/project/fhir/scmsvn/?action=browse&path=%2Ftrunk%2Fbuild%2Fimplementations%2Fjava%2Forg.hl7.fhir.convertors%2Fsrc%2Forg%2Fhl7%2Ffhir%2Fconvertors%2F

view this post on Zulip Grahame Grieve (Jan 27 2018 at 17:17):

@James Agnew a question about cloning date times:

view this post on Zulip Grahame Grieve (Jan 27 2018 at 17:17):

thanks.

view this post on Zulip Grahame Grieve (Jan 27 2018 at 17:17):

org.hl7.fhir.dstu3.model.DateType tgt = new org.hl7.fhir.dstu3.model.DateType(src.getValue());

view this post on Zulip Grahame Grieve (Jan 27 2018 at 17:17):

this changes the timezone of the date - why?

view this post on Zulip Chris Grenz (Jan 27 2018 at 18:03):

{
    "resourceType": "Patient",
    "name": [
        {  "text": "Eve Everywoman",
            "family": [
                "Everywoman1"
            ],
            "given": [
                "Eve"
            ]
     }]}

view this post on Zulip Chris Grenz (Jan 27 2018 at 18:03):

^^^^. Very simple r2 content to POST

view this post on Zulip Chris Grenz (Jan 27 2018 at 18:03):

In r2, name.family is an array, in r3+ it's a string

view this post on Zulip James Agnew (Jan 27 2018 at 20:06):

@Grahame Grieve Java Date objects don't hold a timezone, so that way of cloning would switch to the system local timezone.. I'm really thinking about moving to using one of the Java 8 Date replacements instead of Date in the R4 model for this and a bunch of other reasons...

You can work around this by doing:

org.hl7.fhir.dstu3.model.DateType tgt = new org.hl7.fhir.dstu3.model.DateType(src.getValueAsString());

view this post on Zulip Patrick Werner (Jan 27 2018 at 20:10):

+1 for switching to java.time.*

view this post on Zulip James Agnew (Jan 27 2018 at 20:15):

Yeah it would be a huge improvement... I've held back for a long time only because HAPI currently officially supports Java 7, with Android being the main driver for that.

These days though, I'd say the proportion of android devices that can't support Java 8 is getting pretty small

view this post on Zulip Richard Ettema (Jan 27 2018 at 20:16):

+1

view this post on Zulip Kevin Olbrich (Jan 27 2018 at 21:10):

Proposed Accept Header rules:
1. Specify preferred FHIR versions, in order of preference
2. Don't return an error status for unknown versions
3. Ignore the patch version number (3rd in a semantic version string)
4. If no version is specified use a default version
5. Don't use the `q` parameter.

Example Accept Header:
application/fhir+json; fhir-version=3.0, application/fhir+json; fhir-version=1.0.2, application/fhir+json, application/json+fhir, application/json

Notes:
|-------------------------------------------+-------------|
| application/fhir+json; fhir-version=3.0   | FHIR 3.0    |
| application/fhir+json; fhir-version=1.0.2 | FHIR 1.0    |
| application/fhir+json                     | FHIR >= 1.8 |
| application/json+fhir                     | FHIR < 1.8  |
| application/json                          | Any version |
|-------------------------------------------+-------------+

Server should pick the first one in the list that it can handle, respond appropriately, and always return the version number in the Content-Type header of the response.

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

I don't understand rule 2

view this post on Zulip Kevin Olbrich (Jan 27 2018 at 21:16):

if someone were to specify application/fhir+json; fhir-version=DSTU2 (or any unrecognized version), the server should ignore it, not return a 406 status code.

view this post on Zulip Grahame Grieve (Jan 27 2018 at 21:18):

well, it just seems odd - the normal rules are that you pick the accept format you want to from the list in the headers.

view this post on Zulip Grahame Grieve (Jan 27 2018 at 21:18):

2 makes sense as you describe it, excpt that you haveto return an error if that's the only one

view this post on Zulip Kevin Olbrich (Jan 27 2018 at 21:19):

ok, that's probably true. Although you might treat that as if no Accept header had been passed at all.

view this post on Zulip James Agnew (Jan 27 2018 at 21:30):

This is a neat Stream, I hadn't really given this idea much thought, but now that I'm here..... This would probably be pretty easy to implement using the converters and a HAPI interceptor. I'm gonna give that a whirl.

view this post on Zulip Kevin Olbrich (Jan 27 2018 at 22:46):

The $versions operation to discover supported versions will fail (probably with a 404) on servers that haven't implemented multiple version support. In this case we should probably fall back to using the version specified in the /metadata endpoint.

view this post on Zulip Grahame Grieve (Jan 28 2018 at 14:00):

so do we want to do a break out today to discuss progress? (@Chris Grenz @Kevin Olbrich @Bradley Strecker @Jenni Syed @Lloyd McKenzie )

view this post on Zulip Lloyd McKenzie (Jan 28 2018 at 14:16):

I'm booked from 10-11ish, but available otherwise

view this post on Zulip Grahame Grieve (Jan 28 2018 at 14:53):

yes we'll do a stand up meeting outside immediately after the announcements end @Ewout Kramer @James Agnew

view this post on Zulip Grahame Grieve (Jan 28 2018 at 15:07):

https://makandracards.com/makandra/36457-angularjs-how-to-force-content-type-on-get-and-delete-requests

view this post on Zulip Chris Grenz (Jan 28 2018 at 17:12):

Seems to be at least some consensus on Kevin's summary above. Here's open questions remaining (that I've heard, maybe from the small voice in my head!):

Mapping/Content:

  • Should there be a "standard" mapping between versions, and how strongly should we encourage/require the use of the standard mappings?
  • How should content added/removed in versions be represented? Seems like the logical answer is standard extensions for elements and contained resources for "split out" resources. Ex. r2 Practitioner with roles becomes an r3 Practitioner with contained PractitionerRole resources, or, ValueSets with contained CodeSystems.
  • In the (not few) cases where mapping is largely nonsensical or with with exceptionally poor semantics, should a lowest common denominator approach be taken or should the request simply be rejected?
  • There is an implicit (I think?) requirement that any resource (esp. Bundle) be consistently a single version. While there's been some pushback on this, I think this rule remains generally accepted?

API:

  • Today, versioning applies ONLY to the content accepted and/or returned. The operation of the API itself (query parameters, validation logic, etc.) remain tied to the endpoint. Implementation of a complete API versioning is very problematic in most current implementations, especially those that use POJO/POCO serialization, indexing, etc.
  • The content negotiation method with multiple versions prevents proper application of API versioning since the client wouldn't be able to craft a correct URL/query string, operation call, or even server conformance request without knowing the version.

view this post on Zulip Grahame Grieve (Jan 28 2018 at 17:14):

@Kevin Olbrich can you write up a summary of what we talked about this morning? That will address some of Chris's open issues

view this post on Zulip Kevin Olbrich (Jan 28 2018 at 19:12):

working on that now.

view this post on Zulip Kevin Olbrich (Jan 28 2018 at 20:25):

One area I think we overlooked is the _format query parameter.

view this post on Zulip Grahame Grieve (Jan 28 2018 at 20:35):

oh?

view this post on Zulip Jenni Syed (Jan 28 2018 at 20:35):

I feel like _format should act the same as application/fhir+json w/o version

view this post on Zulip Kevin Olbrich (Jan 28 2018 at 20:37):

why without?

view this post on Zulip Jenni Syed (Jan 28 2018 at 20:43):

More clarification: I think it shouldn't be possible for the "json" and "xml" values. Full mime type option - maybe?

view this post on Zulip Jenni Syed (Jan 28 2018 at 20:46):

our server doesn't currently support the full mime type in the _format, mostly because I've never seen someone try that instead of just "json" and "xml"

view this post on Zulip Chris Grenz (Jan 28 2018 at 21:03):

IMO _format should accept exactly the same as Accept (GET/HEAD) or Content-Type (POST/PUT)

view this post on Zulip James Agnew (Jan 28 2018 at 22:00):

I have actually been successful.. Still redeploying to the public server, but I have a working implementation of this pattern going.

view this post on Zulip Grahame Grieve (Feb 16 2018 at 00:34):

@Kevin Olbrich do we want to repeat this track in Cologne. (I do)

view this post on Zulip Grahame Grieve (Feb 16 2018 at 00:34):

any differences now that we've done it once?

view this post on Zulip Kevin Olbrich (Feb 16 2018 at 00:36):

I think it's worth another round. We may identify a few more edge cases. I would want to try and get a few people with servers and a few with clients to try out some scenarios and try to find out where the approach falls over.

view this post on Zulip Grahame Grieve (Feb 16 2018 at 00:36):

do you have any idea whether you'll be there?

view this post on Zulip Kevin Olbrich (Feb 16 2018 at 00:37):

Not confirmed yet, but leaning towards yes.

view this post on Zulip Grahame Grieve (Feb 16 2018 at 00:37):

great.

view this post on Zulip Kevin Olbrich (Feb 16 2018 at 00:37):

I'll let you know when I have confirmation.

view this post on Zulip Grahame Grieve (Feb 16 2018 at 00:37):

ok

view this post on Zulip Grahame Grieve (Feb 16 2018 at 00:37):

I guess we should write the +fhir-version parameter into the spec before we ballot normative

view this post on Zulip Kevin Olbrich (Feb 16 2018 at 00:38):

I agree


Last updated: Apr 12 2022 at 19:14 UTC