Stream: implementers
Topic: Versioned API Connectathon Track
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?
Grahame Grieve (Dec 23 2017 at 22:44):
btw, my server does scenarios 1 and 2 right now, but not 3 or 4
Abbie Watson (Dec 27 2017 at 02:07):
Versioning like how Aegis/Touchstone recommends? Within the URL?
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
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.
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.
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.
Grahame Grieve (Dec 27 2017 at 09:34):
I only support scenarios 1 and 2 at present; I have't decided about 3
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.
Grahame Grieve (Dec 27 2017 at 21:39):
code system supplements are new in R4
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.
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.
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
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.
Grahame Grieve (Jan 02 2018 at 20:33):
we certainly don't want the revision number in the version
Grahame Grieve (Jan 02 2018 at 20:33):
3.0.0 and 3.0.1 and 3.0.x are all compatible
Grahame Grieve (Jan 02 2018 at 20:34):
that's why the connectathon write up specifies r2 / r3 / r4 instead of the semver version
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
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.
Grahame Grieve (Jan 02 2018 at 20:51):
so ok, that's just content negotiation as envisaged in the connectathon write up
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/
Grahame Grieve (Jan 02 2018 at 21:01):
wiki specifies a content type parameter
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.
Grahame Grieve (Jan 02 2018 at 21:22):
except for r3 vs 3.0
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.
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
Grahame Grieve (Jan 02 2018 at 21:34):
feel free to add clarifying text to the wiki btw
Kevin Olbrich (Jan 02 2018 at 21:52):
Why did you call the version r3
instead of just 3
or 3.0
?
Grahame Grieve (Jan 02 2018 at 22:05):
that's the official product name now
Grahame Grieve (Jan 09 2018 at 02:17):
Grahame Grieve (Jan 09 2018 at 02:17):
FYI
Grahame Grieve (Jan 20 2018 at 20:09):
I have upgraded test.fhir.org to better support the versioned API track.
Grahame Grieve (Jan 20 2018 at 20:10):
test.fhir.org runs 3 end-points:
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.
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:
Grahame Grieve (Jan 20 2018 at 20:12):
GET http://test.fhir.org/r3/Patient/example Accept: application/fhir+xml; fhir-version=r4
Grahame Grieve (Jan 20 2018 at 20:12):
and you'll get the r3 patient resource converted to r4
Grahame Grieve (Jan 20 2018 at 20:13):
The conversion is performed by the Java version conversion code in the Java reference implementation
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
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?
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?
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.
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.
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).
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.
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'.
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
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
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.
Grahame Grieve (Jan 20 2018 at 22:37):
well, it's something people can choose to do, if the connectathon test track goes ok
Bradley Strecker (Jan 27 2018 at 15:53):
Cerner staging test url: https://fhir-open.stagingcerner.com/stu3/fb8067d7-e012-4703-8888-17b86d11f0f8/
Grahame Grieve (Jan 27 2018 at 15:58):
@Bradley Strecker : why list 'r3' and '3.0'?
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" } ] }
Grahame Grieve (Jan 27 2018 at 16:00):
but when the accept type is application/json, the return should be
Grahame Grieve (Jan 27 2018 at 16:00):
{ "versions": ["r3", "3.0"] }
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
"
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
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
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
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
Grahame Grieve (Jan 27 2018 at 16:10):
ok; understand. well, the, what's a resource I can fetch on that server? a patient?
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
Grahame Grieve (Jan 27 2018 at 16:13):
thx
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
Grahame Grieve (Jan 27 2018 at 16:16):
The Accept fhir-version is invalid. It must be one of: r3, 3.0
Grahame Grieve (Jan 27 2018 at 16:16):
It would be better if this was an OperationOutcome
Bradley Strecker (Jan 27 2018 at 16:23):
@Grahame Grieve https://fhir-open.stagingcerner.com/stu3/fb8067d7-e012-4703-8888-17b86d11f0f8/Encounter?patient=4330902
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
Grahame Grieve (Jan 27 2018 at 17:17):
@James Agnew a question about cloning date times:
Grahame Grieve (Jan 27 2018 at 17:17):
thanks.
Grahame Grieve (Jan 27 2018 at 17:17):
org.hl7.fhir.dstu3.model.DateType tgt = new org.hl7.fhir.dstu3.model.DateType(src.getValue());
Grahame Grieve (Jan 27 2018 at 17:17):
this changes the timezone of the date - why?
Chris Grenz (Jan 27 2018 at 18:03):
{ "resourceType": "Patient", "name": [ { "text": "Eve Everywoman", "family": [ "Everywoman1" ], "given": [ "Eve" ] }]}
Chris Grenz (Jan 27 2018 at 18:03):
^^^^. Very simple r2 content to POST
Chris Grenz (Jan 27 2018 at 18:03):
In r2, name.family is an array, in r3+ it's a string
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());
Patrick Werner (Jan 27 2018 at 20:10):
+1 for switching to java.time.*
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
Richard Ettema (Jan 27 2018 at 20:16):
+1
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.
Grahame Grieve (Jan 27 2018 at 21:15):
I don't understand rule 2
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.
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.
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
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.
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.
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.
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 )
Lloyd McKenzie (Jan 28 2018 at 14:16):
I'm booked from 10-11ish, but available otherwise
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
Grahame Grieve (Jan 28 2018 at 15:07):
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.
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
Kevin Olbrich (Jan 28 2018 at 19:12):
working on that now.
Kevin Olbrich (Jan 28 2018 at 20:25):
One area I think we overlooked is the _format
query parameter.
Grahame Grieve (Jan 28 2018 at 20:35):
oh?
Jenni Syed (Jan 28 2018 at 20:35):
I feel like _format should act the same as application/fhir+json w/o version
Kevin Olbrich (Jan 28 2018 at 20:37):
why without?
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?
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"
Chris Grenz (Jan 28 2018 at 21:03):
IMO _format should accept exactly the same as Accept (GET/HEAD) or Content-Type (POST/PUT)
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.
Grahame Grieve (Feb 16 2018 at 00:34):
@Kevin Olbrich do we want to repeat this track in Cologne. (I do)
Grahame Grieve (Feb 16 2018 at 00:34):
any differences now that we've done it once?
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.
Grahame Grieve (Feb 16 2018 at 00:36):
do you have any idea whether you'll be there?
Kevin Olbrich (Feb 16 2018 at 00:37):
Not confirmed yet, but leaning towards yes.
Grahame Grieve (Feb 16 2018 at 00:37):
great.
Kevin Olbrich (Feb 16 2018 at 00:37):
I'll let you know when I have confirmation.
Grahame Grieve (Feb 16 2018 at 00:37):
ok
Grahame Grieve (Feb 16 2018 at 00:37):
I guess we should write the +fhir-version parameter into the spec before we ballot normative
Kevin Olbrich (Feb 16 2018 at 00:38):
I agree
Last updated: Apr 12 2022 at 19:14 UTC