Version Strategy for API

1,338 views
Skip to first unread message

Rohit Goyal

unread,
Jun 17, 2013, 9:09:58 AM6/17/13
to api-...@googlegroups.com

We are creating a REST API that will be used by many consumers. For version, we decided to use Accept header. Consumer sends requested version in Accept header (application/json,version=1.0). As part of first API, we introduced 30 resources, all tagged as version 1.0

Now we putting standards on how the version-ing of API will work

1) If we change in any resource which is transparent to consumer, we call that minor version. Consumer will still send the same version (say 1.0) which internally will be routed to correct version of resource. When I say correct version of resource, I meant that we maintain a technical version for each resource and at the entry point, we map incoming API version to technical version. So consumer will still send the request with 1.0 which will be internally routed to 1.x technical version of the resource. 

2) If a change is not transparent to consumer, we call that major change. In this case consumer has to send the new decided version with request. 

Here the problem comes...

Say we had 30 resources, all tagged as 1.0. We changed 2 resources which considered as major change, for that we asked consumer to send the new version, lets say 2.0
But all other 28 resources are not changed. But because now consumer has moved to new major version of API (2.0), the unchanged resource should respond with 2.0 as well.
(Imp point to note here that consumer always rely on one major version. It's not possible that consumer send 1.0 for few resources and 2.0 for few others. If consumer moves to 2.0, all resources under the API should respond with 2.0)

To respond unchanged 28 resources work with 2.0, we are considering 2 options
1) Create copy for all 28 resources. That way we will have separate implementation for all resources comes under 2.0. It require lot of efforts everytime and go against the re-usability principal

2) Reuse existing ones. At the entry we decide that if incoming is 2.0 and matches the URI of unchanged resource, route to existing one. 

which you guys think is good to go with? Any other approach/suggestion?

Thanks
Rohit 

igtsvi

unread,
Jun 17, 2013, 12:41:50 PM6/17/13
to api-...@googlegroups.com
I am using exactly the same strategy with my enterprise-level CMS API. Once the version goes up by one, all unchanged endpoints answer to the next version (#2 in your list). We maintain one source tree without duplication. Only changes are versioned.

igtsvi

Repenning, Jack

unread,
Jun 17, 2013, 2:46:46 PM6/17/13
to api-...@googlegroups.com
On Jun 17, 2013, at 6:09 AM, Rohit Goyal <rohit....@gmail.com> wrote:

> To respond unchanged 28 resources work with 2.0, we are considering 2 options
> 1) Create copy for all 28 resources. That way we will have separate implementation for all resources comes under 2.0. It require lot of efforts everytime and go against the re-usability principal
>
> 2) Reuse existing ones. At the entry we decide that if incoming is 2.0 and matches the URI of unchanged resource, route to existing one.
>
> which you guys think is good to go with? Any other approach/suggestion?

I think this is really a question about your framework: how does it support best such policies?

Speaking from within the Ruby on Rails framework:

- I have chosen to put the version in the URL, rather than in the headers; this scenario is a big part of the reason why.

- Internally, the reuse of most of the implementation is achieved by "scope" statements within config/routes.rb. Requests whose implementation hasn't changed get routed to the existing implementation; requests whose implementation has changed get routed to the new code.

- All implementations use the URL helper functions provided lavishly by the Rails framework: you don't return "https://my.host.com/api/v2/resources/37" in links or similar places; rather, you return whatever Rails provides as the return value for resource_url(37). If the incoming request used /api/v1/.., so also will the helper-function value; if the incoming request was to /api/v2/..., then so also will be the helper-function value.

Other frameworks will have answers of their own. There might even be a clever Rails way (unknown to me) to do it in headers. I would be interested in seeing any of that.

--
Jack Repenning
Repenni...@gmail.com

Steve Klabnik

unread,
Jun 17, 2013, 7:16:52 PM6/17/13
to api-...@googlegroups.com
As someone who's a big proponent of hypermedia and has commit to
Rails, you _can_ do it in the headers, but I don't think that's the
right way.

If you're building hypermedia stuff, the right answer is 'dont
version,' the next best answer or the answer if you're _not_ building
hypermedia stuff is 'put the version in the URI.'

Peter Monks

unread,
Jun 17, 2013, 7:53:45 PM6/17/13
to Steve Klabnik, api-...@googlegroups.com
G'day Steve,

Is there a comprehensive treatment that you're aware of that explains how hypermedia stuff obviates the need to version?

I'm specifically interested in how hypermedia eliminates the problems caused by compatibility-breaking representation changes i.e. property renames, removals, data type, cardinality & manditoriality changes, format changes (XML -> JSON) and so on.

Thanks!
Peter
 

 


--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group and stop receiving emails from it, send an email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft.
For more options, visit https://groups.google.com/groups/opt_out.



Steve Klabnik

unread,
Jun 17, 2013, 9:07:22 PM6/17/13
to Peter Monks, api-...@googlegroups.com
I wrote about it in "Designing Hypermedia APIs". The chapter is called
"Versioning is an anti-pattern," and you may be able to find a link
online; it used to be freely available, but isn't any more. Here's a
copy in ReST format: https://gist.github.com/steveklabnik/5801884

Repenning, Jack

unread,
Jun 17, 2013, 9:21:24 PM6/17/13
to api-...@googlegroups.com, Peter Monks
The problem I see here is that, very roughly speaking, what this says about compatibility-breaking changes is "Don't Do That." This is excellent advice, and I endorse it whole-heartedly. But, IME, sooner or later some Marketeer or Executive is going to insist on Doing It Anyway. And then some existing, high-dollar-value customer is going to force you to keep the old way around for longer than you find comfortable.

Accordingly, I find a more practical guideline to be:

1. Don't ever break compatibility. Ever.
2. Except when you have to.
3. And always always always build versioning into your API (including allowances for co-deployed concurrent incompatible versions).

--
Jack Repenning
Repenni...@gmail.com

Steve Klabnik

unread,
Jun 17, 2013, 9:23:28 PM6/17/13
to api-...@googlegroups.com, Peter Monks
There is no difference between breaking backwards compatibility and
shutting off an older version of the API. You're no better off.

Kevin Swiber

unread,
Jun 17, 2013, 9:35:14 PM6/17/13
to api-...@googlegroups.com, Peter Monks
I assert this doesn't work for the long-term in production APIs.
Sometimes you need to do a major revision that breaks backwards
compatibility. This is true for all software.

Release a new version with a different root URI. Use a sunset schedule
and communicate before retiring an old one. Again, this is major
revision stuff. After an API is at v1, it should be a long time before
this is necessary.


Sent from my iPhone

On Jun 17, 2013, at 9:23 PM, Steve Klabnik <st...@steveklabnik.com> wrote:

> There is no difference between breaking backwards compatibility and
> shutting off an older version of the API. You're no better off.
>

Steve Klabnik

unread,
Jun 17, 2013, 9:41:23 PM6/17/13
to api-...@googlegroups.com, Peter Monks
Well, I assert the opposite. I give HTML and the WWW as my evidence.
HTML has been backwards compatible for a looooong damn time, and is in
production in quite a few places, I hear.

It just takes care.

Steve Klabnik

unread,
Jun 17, 2013, 9:42:20 PM6/17/13
to api-...@googlegroups.com
I should also say this: this is why I posed this initially as the
'best' and 'not the best' options. I think versioning is fine, but I
don't think it's optimal. We can (and have) do better.

Kevin Swiber

unread,
Jun 17, 2013, 9:45:24 PM6/17/13
to api-...@googlegroups.com, Peter Monks
That's apples vs oranges.

If you built a Web scraper for an HTML site, it might break with each
deployment.

Understanding a media type is not the same as understanding
application semantics or the shape/hierarchy of message elements.

Sent from my iPhone

Mike Schinkel

unread,
Jun 17, 2013, 11:55:00 PM6/17/13
to api-...@googlegroups.com
Probably the best post on the subject is this one:


-Mike 


Steve Klabnik

unread,
Jun 18, 2013, 2:00:19 AM6/18/13
to api-...@googlegroups.com
Thanks Mike, that post does say basically everything I'm trying to say.

Philip Nelson

unread,
Jun 18, 2013, 6:28:06 AM6/18/13
to api-...@googlegroups.com
One of the things that always strikes me about versioning discussions is that we seem to miss the impact over time to the client. This conversation is no exception, talking mostly about an orderly transition from v1 to v2. What is really at stake is communicating how long a client will work without changes. 

Let's say you commit to maintaining 2 major versions, and you will change them no more than once per year. So the client says, great I've got 2 years with no changes.They may decide to go with the most recent of course, and then have another two years, or stay with the older more stable version at which point they update once per year like somebody who wants to keep up with the latest and greatest. So all you've actually accomplished is delaying the point at which they have to do annual updates. 

Shorten this update cycle and the problem becomes even more obvious. I think it is just as reasonable to say what your update schedule is and just get users to make that choice when they decide to use your api and skip versioning altogether, All the other advice given to allow non-breaking changes to be safely implemented apply here too, maybe your versioning needs aren't as great as you think. 


On Tue, Jun 18, 2013 at 1:00 AM, Steve Klabnik <st...@steveklabnik.com> wrote:
Thanks Mike, that post does say basically everything I'm trying to say.

Repenning, Jack

unread,
Jun 18, 2013, 1:36:55 PM6/18/13
to api-...@googlegroups.com, Peter Monks

On Jun 17, 2013, at 6:41 PM, Steve Klabnik <st...@steveklabnik.com> wrote:

> Well, I assert the opposite. I give HTML and the WWW as my evidence.
> HTML has been backwards compatible for a looooong damn time, and is in
> production in quite a few places, I hear.

A common metaphoric inference, but flawed. HTML and WWW are successful, yes, but that's because they always have a human in the loop. If the links on my favorite web page move, or new capabilities are added, or a new required field appears, I can grok and cope. (I may curse, but that's a different problem.)

With an API, the whole point is to get the humans out of that loop, or as nearly so as possible. There's a human developer involved in creating the initial app, of course, and there may even be a human developer on call if things go south. But if I impose an incompatible change via API, my users (who are programs) begin failing, and my customers (who employ that on-call developer) lose money, and my employer gets an angry call. Bad blood all around. It's poor consolation at best if the new requirement is well documented, or even self-evident to a human: by the time the human returns to the loop, problems have already occurred.

I've seen hypermedia advocates claim to have this problem solved, but I've never seen the claim made convincing--indeed, I'm never quite sure they're actually solving the problem I just presented. The "solution" seems to be to make ever more elaborate meta-architectures. But if the goal is to make something client code can follow, no matter what its zigs and zags, I'm not convinced: the requisite client complexity seems to grow without bound, and I think Dr. Goedel's (anti)Completeness Theorem has something to say on the matter. And if the goal is only to make things evident to the returned-to-the-loop human ... that can be done much more simply, such as by including links to documents with any error return.


--
Jack Repenning
Repenni...@gmail.com

Peter Monks

unread,
Jun 18, 2013, 1:57:12 PM6/18/13
to Repenning, Jack, api-...@googlegroups.com
On Jun 18, 2013, at 10:36 AM, "Repenning, Jack" <repenni...@gmail.com> wrote:
With an API, the whole point is to get the humans out of that loop, or as nearly so as possible. There's a human developer involved in creating the initial app, of course, and there may even be a human developer on call if things go south. But if I impose an incompatible change via API, my users (who are programs) begin failing, and my customers (who employ that on-call developer) lose money, and my employer gets an angry call. Bad blood all around. It's poor consolation at best if the new requirement is well documented, or even self-evident to a human: by the time the human returns to the loop, problems have already occurred.

I've seen hypermedia advocates claim to have this problem solved, but I've never seen the claim made convincing--indeed, I'm never quite sure they're actually solving the problem I just presented.

Thanks Jack - this statement strongly resonates for me.  Now don't get me wrong - it's wonderful that hypermedia solves a bunch of problems around URLs etc., but I've struggled for some time now to understand if/how it solves the "data compatibility" side of the equation.  I had come to the conclusion that it doesn't, but wasn't confident that wasn't due to some lack of understanding on my part - this discussion has put my mind to rest (if you'll pardon the pun...).

The takeaway for me is that versioning is basically an insurance policy - the goal is to never have to call upon it, but when you need it, you really really need it, and you can't introduce it "just in time" - it's got to be there from the get-go (even as you hope that it's never needed).

Thanks everyone!
Peter

mca

unread,
Jun 18, 2013, 4:29:34 PM6/18/13
to api-...@googlegroups.com, Repenning, Jack
Versioning is not a feature, it's a technique; a technique for managing change. It is not the only way to manage change in a distributed system and it's not always the best way.

From a server POV, versioning is the easiest way to handle change. just change all the parts of the existing system you don't like, don't worry about breaking changes for any existing client implementation, just claim a new version number and let client apps sort it out.

When the server implementation "owns" all the client implementations, it's relatively easy to co-ordinate all the changes. When the server implementation has not control over the clients (widely dispersed client apps using an "open api" that does not require registration to use, etc.) then there is almost no way to coordinate client releases w/ server releases. This is when the version pattern breaks clients - sometimes in unpredictable ways.

Any time i can introduce change into a distributed system w/o breaking clients, that's what i do. i _rarely_ find i MUST break clients in order to support the change i need to make. for that reason, i rarely find using the version pattern useful.


Mike Schinkel

unread,
Jun 18, 2013, 4:41:55 PM6/18/13
to api-...@googlegroups.com
On Jun 18, 2013, at 1:36 PM, "Repenning, Jack" <repenni...@gmail.com> wrote:
On Jun 17, 2013, at 6:41 PM, Steve Klabnik <st...@steveklabnik.com> wrote:

Well, I assert the opposite. I give HTML and the WWW as my evidence.
HTML has been backwards compatible for a looooong damn time, and is in
production in quite a few places, I hear.

A common metaphoric inference, but flawed. HTML and WWW are successful, yes, but that's because they always have a human in the loop.

...

I've seen hypermedia advocates claim to have this problem solved, but I've never seen the claim made convincing--indeed, I'm never quite sure they're actually solving the problem I just presented.

I agree, and disagree at the same time.  :)

I agree that presenting HTML as the archetype for a successful hypermedia system is a flawed metaphor because of fact it's designed to have a human sit in the middle. 

And for most of the time I've been studying REST (since 2006) I've agreed with your entire thesis that "to make something client code can follow the requisite client complexity grows without bounds" and so on these hypermedia lists I've felt like the little kid who keep telling the emperor he had no clothes.

But after much recent studying of Roy's comments here[1] I've achieved an epiphany about hypermedia, if you can call a very gradual understanding "an epiphany" and this is where I disagree (and think/hope you'll agree once I explain.)

Most of the "elaborate meta-architectures" you describe appear to be trying to create a *single media type* designed to be used for hypermedia and infuse with meta with the apparent goal of enabling fully automated processing for any arbitrary use-case. And the focus on the lists I follow have been on hypermedia to the exclusion of other factors (or so it seems from the outside looking in.)

However, my understanding of Roy's comments tell me that the proper approach to REST is not to create an uber-type capable of being the be-all, end-all of hypermedia but instead to create a small number of use-case specific media types that enable client agents to be built that have in-built knowledge of the media types.

For example, consider an "application/invoice" media type that is as simple as early HTML, with XML-like elements that designate things like "item" and "billto" and "shipto" and that embed URLs where appropriate.  If such a media type existed and was in use by enough users to gain critical mass then this media type could be the API equivalent for invoices that text/html is for human navigable hypertext documents and then many could/would build clients that are fully aware of "application/invoice."  (This is the part where I disagreed.)

However this hasn't happened.  Why?  Having every individual mint a new media type for ever new project is not the answer because the benefit only really accrues when there is a large number of systems that can process the media type exist, either via one processing library used by many, or many different processing libraries also collectively used by many.

In order to get critical mass you need most to agree on the use of the same media type for similar use-cases but in the case of something like "application/invoice" most of those who might use it and drive adoption are competitors. And without the lack of an external catalyst driving a consolidation towards a standard competitors rarely collaborate to converge. As such as have ongoing chaos much like the integration chaos that existing pre-commercial web in the "client-server" days.

What will it take to change it?  An entity like the W3C or an individual with enough clout  could convene a group to be the external catalyst to identify major use-cases and drive consolidation to a standard (Who? Roy could do it, but it's obviously not his focus/interest.)  Or related organizations like Apigee and their competitors could get together to drive it since they are not competing on things like invoice processing are not their core strategy but having exponential API usage growth would benefit them all.

Or it might simply take a lot more time in evolution where many developers try to do it better until a one or more hit on successes that gain traction and enough take notice to drive change.

Or in the worst case, no change ever occurs because no entity or person (is able to or wants to) drive this change and no developers hit on broad success in anything they try.

Me, I'd really like to see the first option happen because it would mean seeing useful results sooner than later. But what is actually going to happen is anybody's guess.

BTW, how this relates to versioning is that an "application/invoice" media type would really need to be evolved in backward compatible ways as HTML has (mostly) been evolved.


On Jun 18, 2013, at 1:57 PM, Peter Monks <pmo...@alfresco.com> wrote:
The takeaway for me is that versioning is basically an insurance policy - the goal is to never have to call upon it, but when you need it, you really really need it, and you can't introduce it "just in time" - it's got to be there from the get-go (even as you hope that it's never needed).

+1

On Jun 18, 2013, at 4:29 PM, mca <m...@amundsen.com> wrote:
Any time i can introduce change into a distributed system w/o breaking clients, that's what i do. i _rarely_ find i MUST break clients in order to support the change i need to make. for that reason, i rarely find using the version pattern useful.

+1

-Mike

Repenning, Jack

unread,
Jun 18, 2013, 5:45:53 PM6/18/13
to api-...@googlegroups.com
On Jun 18, 2013, at 1:41 PM, Mike Schinkel <mi...@newclarity.net> wrote:

But after much recent studying of Roy's comments here[1] I've achieved an epiphany about hypermedia, if you can call a very gradual understanding "an epiphany" and this is where I disagree (and think/hope you'll agree once I explain.)

Well, whatever else happens, I can heartily thank you for clarifying Roy's thoughts on this. I've spent the time, but I can't say I've had the epiphany (slow or otherwise)!

What will it take to change it?  An entity like the W3C or an individual with enough clout  could convene a group to be the external catalyst to identify major use-cases and drive consolidation to a standard (Who? Roy could do it, but it's obviously not his focus/interest.)  Or related organizations like Apigee and their competitors could get together to drive it since they are not competing on things like invoice processing are not their core strategy but having exponential API usage growth would benefit them all.

I've rather gone off standards bodies, lately, but I am rather excited by this one gleam in the dark: there's an Internet Draft proposal to standardize the form of problem-report replies, anyway:


BTW, how this relates to versioning is that an "application/invoice" media type would really need to be evolved in backward compatible ways as HTML has (mostly) been evolved.


Did I miss something, or did you just say "Don't Do That"? ;-)

Mike Schinkel

unread,
Jun 18, 2013, 5:50:42 PM6/18/13
to api-...@googlegroups.com
On Jun 18, 2013, at 5:45 PM, "Repenning, Jack" <repenni...@gmail.com> wrote:
Well, whatever else happens, I can heartily thank you for clarifying Roy's thoughts on this. I've spent the time, but I can't say I've had the epiphany (slow or otherwise)!


If I helped, I'm glad I was able to.  It was certainly not easily groked with the available information, that's for sure.


I've rather gone off standards bodies, lately, but I am rather excited by this one gleam in the dark: there's an Internet Draft proposal to standardize the form of problem-report replies, anyway:



Yes, I saw that.  Frankly I've come to assume that whatever Mark Nottingham comes up with, it's going to be good.


BTW, how this relates to versioning is that an "application/invoice" media type would really need to be evolved in backward compatible ways as HTML has (mostly) been evolved.
Did I miss something, or did you just say "Don't Do That"? ;-)


Let me clarify.  Ideally, it would be backward compatible. In the real world, I don't have a good solution for when it can't be. 

IOW, I'm taking a pass. :)

-Mike

Klaas Jan Wierenga

unread,
Jun 18, 2013, 5:59:47 PM6/18/13
to api-...@googlegroups.com
Hi,

Op 18 jun. 2013, om 22:41 heeft Mike Schinkel <mi...@newclarity.net> het volgende geschreven:
For example, consider an "application/invoice" media type that is as simple as early HTML, with XML-like elements that designate things like "item" and "billto" and "shipto" and that embed URLs where appropriate.  If such a media type existed and was in use by enough users to gain critical mass then this media type could be the API equivalent for invoices that text/html is for human navigable hypertext documents and then many could/would build clients that are fully aware of "application/invoice."  (This is the part where I disagreed.)

However this hasn't happened.  Why?  Having every individual mint a new media type for ever new project is not the answer because the benefit only really accrues when there is a large number of systems that can process the media type exist, either via one processing library used by many, or many different processing libraries also collectively used by many.

I guess most of the successful media type like for example image/jpeg, image/png, text/vcard, text/calendar are read-only (immutable) media-types. I don't see the application/invoice media-type being immutable.

Is there some pattern here as to why certain media-types are accepted more readily than others?

Regards,
KJ

Repenning, Jack

unread,
Jun 18, 2013, 6:10:26 PM6/18/13
to api-...@googlegroups.com
On Jun 18, 2013, at 2:59 PM, Klaas Jan Wierenga <k.j.wi...@gmail.com> wrote:

I guess most of the successful media type like for example image/jpeg, image/png, text/vcard, text/calendar are read-only (immutable) media-types. I don't see the application/invoice media-type being immutable.

Is there some pattern here as to why certain media-types are accepted more readily than others?

Well, these examples suggest a pattern: if Someone Else, for their own purposes, has already cast some media type in stone (in the real, non-REST world, that is), then the REST media type can be likewise stoney.

Not so much a "solution," as a "delegation."

Those types are stable because they are the stuff of widespread cooperation: many people implement to those standards so they can cooperate. A camera has to know that the image it stores can be carried all over the world, and eventually rendered by a printer, browser, or projector.

I really don't see the "application/invoice" having that compelling and extensive a collaboration requirement. Invoice-collaboration happens, but it's one-on-one.

Mike Schinkel

unread,
Jun 18, 2013, 6:11:54 PM6/18/13
to api-...@googlegroups.com
On Jun 18, 2013, at 5:59 PM, Klaas Jan Wierenga <k.j.wi...@gmail.com> wrote:
I guess most of the successful media type like for example image/jpeg, image/png, text/vcard, text/calendar are read-only (immutable) media-types. I don't see the application/invoice media-type being immutable.

I don't understand the use of the word "immutable" in this context.  Elaborate?

Is there some pattern here as to why certain media-types are accepted more readily than others?

"Accepted" how, and by whom?

-Mike

Mike Schinkel

unread,
Jun 18, 2013, 6:16:11 PM6/18/13
to api-...@googlegroups.com
On Jun 18, 2013, at 6:10 PM, "Repenning, Jack" <repenni...@gmail.com> wrote:
Well, these examples suggest a pattern: if Someone Else, for their own purposes, has already cast some media type in stone (in the real, non-REST world, that is), then the REST media type can be likewise stoney.

Exactly.

I really don't see the "application/invoice" having that compelling and extensive a collaboration requirement. Invoice-collaboration happens, but it's one-on-one.

Invoice was simply an arbitrary example. 

But then I don't see why it couldn't be compelling.  For example, if there were such an media type I could see someone recording time using Harvest and Harvest could generate an "application/invoice" that gets posted to another company's Xero accounting system, as one of many different ways it could be used.  

So why not?

-Mike

Repenning, Jack

unread,
Jun 18, 2013, 6:24:58 PM6/18/13
to api-...@googlegroups.com
On Jun 18, 2013, at 3:16 PM, Mike Schinkel <mi...@newclarity.net> wrote:

But then I don't see why it couldn't be compelling.  For example, if there were such an media type I could see someone recording time using Harvest and Harvest could generate an "application/invoice" that gets posted to another company's Xero accounting system, as one of many different ways it could be used.  

So why not?

Because everyone's invoicing has idiosyncratic requirements:
 - apply discount code
 - payment terms
 - SKUs and other descriptors
 - apply 1% to Presidential Reelection Fund, or Carbon Offset, or Citizens for Waffle Chicken
 - ...

Either this standard invoice has every feature needed by anyone (which would be impractically unwieldy), or it's extensible (but the extensions still have the same problem), or it evolves as new circumstances arise (i.e., it's not immutable).

Mike Schinkel

unread,
Jun 18, 2013, 6:32:03 PM6/18/13
to api-...@googlegroups.com
On Jun 18, 2013, at 6:24 PM, "Repenning, Jack" <repenni...@gmail.com> wrote:
Because everyone's invoicing has idiosyncratic requirements:

The same is also true for document markup, yet HTML emerged and flourished.  

The way to handle the special cases is to allow non-standard embedded data for those who need special cases and then, over time, the standard could evolve to address common use-cases that were not initially recognized as common.

Either this standard invoice has every feature needed by anyone (which would be impractically unwieldy),

Agree, that would be awful.

or it's extensible (but the extensions still have the same problem), or it evolves as new circumstances arise (i.e., it's not immutable).

Evolution does not require backward incompatibility though. With reasonably intelligent up-front design it should not be too hard to to maintain backward compatibility, in most cases.

And if they screw it use, there can always the version number stored in the media type, worst case. (Not ideal, I admit.)

-Mike


Peter Monks

unread,
Jun 18, 2013, 6:37:07 PM6/18/13
to api-...@googlegroups.com
On Jun 18, 2013, at 3:16 PM, Mike Schinkel <mi...@newclarity.net> wrote:

But then I don't see why it couldn't be compelling.  For example, if there were such an media type I could see someone recording time using Harvest and Harvest could generate an "application/invoice" that gets posted to another company's Xero accounting system, as one of many different ways it could be used.  

Is the invoice for T&M or fixed price work?  Are the payment terms net-30, net-45 or something else?  How are travel expenses split out?  What about tax, foreign currency transactions??  etc. etc. ad nauseam

My point is that while "file" data such as images are simple (there are only so many "sensible" ways images can be represented), structured data is full of all sorts of variances, exceptions, corner cases, assumptions, arbitrary "rules", regulatory restrictions, company-specific policies etc. etc. that makes standardisation unlikely to succeed.

Who here remembers EDI?  More importantly, who here is using or implementing EDI X12 document types today?  I can only recall running into EDI once, and that was back in the 90s - to my mind that speaks a lot to the practical difficulties of standardising business data structures.

Cheers,
Peter

Repenning, Jack

unread,
Jun 18, 2013, 6:43:03 PM6/18/13
to api-...@googlegroups.com
On Jun 18, 2013, at 3:32 PM, Mike Schinkel <mi...@newclarity.net> wrote:

Because everyone's invoicing has idiosyncratic requirements:

The same is also true for document markup, yet HTML emerged and flourished.  

Have I missed something? HTML is a language for describing documents, but I'm not aware of any standard for specific document formats -- "this is how  you make a home page, any nonconforming page may not be served at your http://host/ URL". Unthinkable!

We already have several languages for defining REST payload documents (XMLSchema,  JSON Schema, HAL, and so forth). These are better analogies to HTML. Indeed, the strongest REST-world analogue to HTML would really be XML or JSON.  None of that's particularly in question in this thread. What I thought we were talking about is "using one of those languages to define a canonical form for particular document types, such as application/invoice."

I've seen a lot of invoices on the web, all written in HTML, but none of them in the least "standard."


Steve Klabnik

unread,
Jun 18, 2013, 6:51:38 PM6/18/13
to api-...@googlegroups.com
On 06/18/2013 03:43 PM, Repenning, Jack wrote:
> I'm not aware of any standard for specific document formats

There is a pretty large microformats community that has various specs
for exactly this.

signature.asc

Mike Schinkel

unread,
Jun 18, 2013, 6:55:44 PM6/18/13
to api-...@googlegroups.com
On Jun 18, 2013, at 6:37 PM, Peter Monks <pmo...@alfresco.com> wrote:
Is the invoice for T&M or fixed price work?  Are the payment terms net-30, net-45 or something else?  How are travel expenses split out?  What about tax, foreign currency transactions??  etc. etc. ad nauseam

My point is that while "file" data such as images are simple (there are only so many "sensible" ways images can be represented), structured data is full of all sorts of variances, exceptions, corner cases, assumptions, arbitrary "rules", regulatory restrictions, company-specific policies etc. etc. that makes standardisation unlikely to succeed.

Who here remembers EDI?  More importantly, who here is using or implementing EDI X12 document types today?  I can only recall running into EDI once, and that was back in the 90s - to my mind that speaks a lot to the practical difficulties of standardising business data structures.

That concern applies for (practically) every standard that has and will ever exist.  

The solution is to do the 20% that happens 80% of the time in the standard and allow the special cases to be handled by embedded data.  Then, as time progresses the standard is evolved to include the 20% of the remaining 80% that is used 20% of the time. And so on.

EDI was a nightmare because it did many things badly compared with what we know today to be best practices for large scale long lived interoperable systems. In a nutshell, EDI didn't follow REST. :)

On Jun 18, 2013, at 6:43 PM, "Repenning, Jack" <repenni...@gmail.com> wrote:
Have I missed something? HTML is a language for describing documents, but I'm not aware of any standard for specific document formats-- "this is how  you make a home page, any nonconforming page may not be served at your http://host/ URL". Unthinkable!

Of course not.  Just like you wouldn't need a different media type to describe different types of invoices. 

We already have several languages for defining REST payload documents (XMLSchema,  JSON Schema, HAL, and so forth). These are better analogies to HTML. Indeed, the strongest REST-world analogue to HTML would really be XML or JSON.  None of that's particularly in question in this thread. What I thought we were talking about is "using one of those languages to define a canonical form for particular document types, such as application/invoice."

Yes to the latter.  

Your point about the former means that I didn't explain what I was trying to explain well enough because you are taking it in a direction I didn't intend nor envision.

I've seen a lot of invoices on the web, all written in HTML, but none of them in the least "standard."

I have no idea how you arrived on that from what I wrote, but again it was probably my inability to explain well enough.

-Mike

Pat Cappelaere

unread,
Jun 18, 2013, 7:17:49 PM6/18/13
to api-...@googlegroups.com, Repenning, Jack
Of course, nobody wants to break clients.  Problem is that sometimes, some people found that it could happen.
It is fine and dandy to say that the versioning pattern is not useful (or should not be used… or hypermedia solves that problem…)
It seems that many people are not convinced.

So… may be we need a real example that Jack or Mike could provide.  It gets implemented with Hypermedia by Steve or MCA… a major change in spec occurs… and we observe the client to not fail.

Pat.


On Jun 18, 2013, at 4:29 PM, mca <m...@amundsen.com> wrote:

Peter Monks

unread,
Jun 18, 2013, 7:20:43 PM6/18/13
to api-...@googlegroups.com
On Jun 18, 2013, at 3:32 PM, Mike Schinkel <mi...@newclarity.net> wrote:
Evolution does not require backward incompatibility though.

I think this defines the crux of the philosophical difference exposed in this thread - do you believe that hypermedia provides a way to transform what would otherwise be backwards-compatibility-breaking changes to be backwards compatible, or not?

Speaking for myself, I still haven't seen any convincing evidence that hypermedia provides this.  I'm not even sure that I believe that it's possible in theory (whether via hypermedia or some other yet-to-be-invented mechanism).  What I do believe is that such changes will be required of any non-trivial, long-lived app that exposes an API, and that not having an a priori mechanism for dealing with that situation will result in #epicfail.

Ye olde 2x2 matrix is another way to look at it:

                             +---------------+-----------------------------+
                             | No versioning | Versioning                  |
   +-----------------------------------------------------------------------+
   | No incompatible changes | Happy days!   | Happy days!                 |
   +-----------------------------------------------------------------------+
   |   Incompatibile changes | #epicfail     | Unfortunate, but survivable |
   +-----------------------------------------------------------------------+

When looked at this way, it's hard to see the downside of just sticking versioning in then working as hard as you can to avoid needing it.  "What about cost?", you might argue, but in reality there's little up front cost in establishing a versioning mechanism - most of the cost is only incurred if/when a new version becomes necessary (which you're working equally hard to avoid in both cases anyway).

Cheers,
Peter

Kijana Woodard

unread,
Jun 18, 2013, 7:24:12 PM6/18/13
to api-...@googlegroups.com
Reading through this thread, I'm not convinced that a version number actually solves the problem either.


Repenning, Jack

unread,
Jun 18, 2013, 7:24:41 PM6/18/13
to api-...@googlegroups.com
On Jun 18, 2013, at 3:55 PM, Mike Schinkel <mi...@newclarity.net> wrote:

I have no idea how you arrived on that from what I wrote, but again it was probably my inability to explain well enough.

Hmm. OK, to return to the top of this thread ... as best I recall, and deliberately interpreting here and there rather than strictly quoting, since the original language somewhere or other seems to have been misunderstood:

 * The question was asked, "what's the best strategy for versioning an API?" 

 * An answer was suggested, "don't version your API at all, just define hypermedia and don't change those incompatibly."

 * An objection was raised, "that won't avoid version woes, it just moves the locus of turmoil to the media types. You can't define a media type that will survive any conceivable API data change compatibly."

 * You rejoined "Sure you can, as illustrated by the fact that HTML works."

I grant that HTML has shown itself to be remarkably expressive, remarkably robust, and has survived in the face of remarkable evolution (some standardized, some not). But it has not survived without incompatible changes, and it has not survived without versioning. So how is it a counter-example to the claim that "no media type can survive any conceivable change"?

Peter Monks

unread,
Jun 18, 2013, 7:31:17 PM6/18/13
to api-...@googlegroups.com
Care to go into more detail?

Cheers,
Peter


Repenning, Jack

unread,
Jun 18, 2013, 7:32:42 PM6/18/13
to api-...@googlegroups.com
On Jun 18, 2013, at 4:24 PM, Kijana Woodard <kijana....@gmail.com> wrote:

Reading through this thread, I'm not convinced that a version number actually solves the problem either.

What the version number contributes is the ability to keep running the old version for a while, simultaneously with running the new.

If "GET /api/resource/37" originally returned a record that included a field named "name", and it then suddenly returs a record that includes a corresponding field named "shortName", then clients accustomed to fetching the record and using the "name" field will break until they're recoded to use "shortName".

But, if "GET /api/v1/resource/37" returns "name", and "GET /api/v2/resource/37" returns "shortName", both can be served simultaneously, and no code breaks.

If you think such a change is frivolous, I agree. If you think it should simply not be made,  I won't argue. But speaking from personal experience, us sensible ones don't always have the leverage to prevent such travesties. Stuff happens, and you can dig yourself out with far less pain if that "v1" is there from the very beginning.

Kijana Woodard

unread,
Jun 18, 2013, 7:51:58 PM6/18/13
to api-...@googlegroups.com
Given N resources, do they all get versioned together or separately?

If together, the version numbers advance rapidly regardless if the resources a client is interested are actually changing or not. Computing the "effective version" seems to get very complex very quickly.  I'm accessing the site through v2.3. Support sounds hellish. The support person has to grok that the user is actually using v2 of X, v1.2 of Y, and  v1.0 of Z. Next someone calls who is using v1.8. :-(

If separately, complexity from the other direction. The customer would have to understand all these versions and reason about what upgrading Z to 1.1 would mean. Is there feature intersection that necessitates lock step versioning of multiple endpoints in some cases but not others?

How many of either type of version do we support? For how long? Do all these versions run side by side. This sounds harder than trying to make backwards compatible changes which is effectively the same work. At some point, I assume there is persistence and that has to be backwards compatible to support all the versions.

Assume it's really a breaking change, for instance, we can no longer accept orders without some new data field. The advantage to a version number I see is that when "the angry customer calls", you can say "sorry, upgrade to v3".

At that point, you have to communicate the "must upgrade" information and give reasonable time to respond. Seems to be about the same problem if you decide to rename a property and, eventually, delete it.

The last bit of angst I have about version numbers is that, once my app is stable, I'm probably going to avoid upgrading as long as possible. With version numbers, I have to do a big bang upgrade all at once. With a backwards compatible api with the same routes, I can commit the change "name" to "shortname" today, then add "foo" and "bar" tomorrow.


Mike Schinkel

unread,
Jun 18, 2013, 7:52:33 PM6/18/13
to api-...@googlegroups.com
On Jun 18, 2013, at 7:17 PM, Pat Cappelaere <cappe...@gmail.com> wrote:
So… may be we need a real example that Jack or Mike could provide. 

If you re-read you'll see hidden in all the other words that I punted on having a solution for backward in-compatible changes for a media type.  I don't know what to do there.

On Jun 18, 2013, at 7:20 PM, Peter Monks <pmo...@alfresco.com> wrote:
I think this defines the crux of the philosophical difference exposed in this thread - do you believe that hypermedia provides a way to transform what would otherwise be backwards-compatibility-breaking changes to be backwards compatible, or not?

One thing to consider is that an API's services are not a media type nor vice-versa. I introduced the concept of the media type to this thread (possibly off-topic) when Jack mentioned he didn't see how hypermedia actually solved the problem without creating bigger ones (I'm paraphrasing and if I got it wrong, Jack I apologize.)

So I can envision that an API's services are likely more fragile than a media type might be and more in need of versioning. But that's just my hypothesis at this point.

Speaking for myself, I still haven't seen any convincing evidence that hypermedia provides this.  I'm not even sure that I believe that it's possible in theory (whether via hypermedia or some other yet-to-be-invented mechanism).  

To be clear, that's what I believed until very recently, and only recently have I started to believe I finally understand what Roy was saying about hypermedia so many years ago.  Is it a panacea? No. But I think it does provide guidance for circumstances where it can apply; for media types used broadly.

What I do believe is that such changes will be required of any non-trivial, long-lived app that exposes an API, and that not having an a priori mechanism for dealing with that situation will result in #epicfail. ... but in reality there's little up front cost in establishing a versioning mechanism - most of the cost is only incurred if/when a new version becomes necessary (which you're working equally hard to avoid in both cases anyway).

Yep, pretty much agree.

On Jun 18, 2013, at 7:24 PM, "Repenning, Jack" <repenni...@gmail.com> wrote:
I have no idea how you arrived on that from what I wrote, but again it was probably my inability to explain well enough.

 * The question was asked, "what's the best strategy for versioning an API?" 

 ....

 * You rejoined "Sure you can, as illustrated by the fact that HTML works."

Ah I see the confusion, and it was completely my fault. I read your post that talked about hypermedia not working well because of the necessary complexity and I replied to say that I (recently came to) believe that it does work assuming you are using a widely known media type that is specific to the use-case. Of course that hasn't occurred much beyond HTML, RSS, ATOM, etc.

So, I effectively hijacked the thread (sorry) to discuss hypermedia. I actually took a pass on versioning which was the question the thread and I now realize you were focused on. My comments on versioning were limited to implying via mnot's link that versioning is important but should be rarely used, and regarding the versioning of media types for backward incompatible changes, the only answer I have is "Don't do it." (not great, I know.)

-Mike

Peter Monks

unread,
Jun 18, 2013, 8:00:41 PM6/18/13
to api-...@googlegroups.com
If version numbers are advancing rapidly, you're doing it wrong.  A versioning mechanism is only there for unavoidable compatibility breaking changes, which should be a rare exception, not the norm.

Think of it as a life insurance policy - valuable when you need it, but cashing it in implies that something has gone badly wrong.

Cheers,
Peter

 
 

Kijana Woodard

unread,
Jun 18, 2013, 8:09:33 PM6/18/13
to api-...@googlegroups.com
So what does a version number mean?
Things change all the time and it's no big deal, but every now and then, oops, move to v2?
If it's a certain type of breaking change, then the old version might be immediately DOA anyway. Then what?

I suppose it preserves the root url for when you've really decided that your current efforts have no future, i.e.
vs

Honestly, I think the "example.com" APIs are all radically different in our heads. We're each imagining different scenarios and then thinking "this is perfect" or "that would never work, how silly".

Repenning, Jack

unread,
Jun 18, 2013, 8:13:47 PM6/18/13
to api-...@googlegroups.com
On Jun 18, 2013, at 4:51 PM, Kijana Woodard <kijana....@gmail.com> wrote:

> If together, the version numbers advance rapidly regardless if the resources a client is interested are actually changing or not. Computing the "effective version" seems to get very complex very quickly. I'm accessing the site through v2.3. Support sounds hellish. The support person has to grok that the user is actually using v2 of X, v1.2 of Y, and v1.0 of Z. Next someone calls who is using v1.8. :-(

Remember that I advocate advancing the version indicator only as a last resort. Most changes can and should be made in a backwards-compatible way, not requiring a version roll. As Peter has said, it's insurance against something you continue to do whatever you can to avoid.

If we succeed at that, then we should not complicate anyone's life by multiplying version indications. One version number covers the whole API (the whole URL space below /api/v2/). The things that don't change between v1 and v2 just ... don't change.

> How many of either type of version do we support? For how long? Do all these versions run side by side. This sounds harder than trying to make backwards compatible changes which is effectively the same work. At some point, I assume there is persistence and that has to be backwards compatible to support all the versions.

Again, I advocate backwards compatibility as the first line of defense; version-rolling only comes when B-C fails. But to respond to your "how many / how long" line of questioning: as few, and as briefly, as you can arrange.

* If you're actually building the API underneath a web app you also build, you can deploy both changes in a coordinated way. "How many" would be only two (one old, one new), and "how long" would be "your page cache time-out" -- which, actually, you control, so there are tricks available like setting it Really Short in anticipation of the change.

* If you're building an API under a downloaded/installed app, still under your control, then you might stretch "how long" to approximate your observed upgrade patterns.

* But if you're building for someone else to code to, and if at least some of those "someone elses" has powerful leverage (like, say, providing over half your revenue), you may end up doing what you're told, instead of what's right.

> Assume it's really a breaking change, for instance, we can no longer accept orders without some new data field. The advantage to a version number I see is that when "the angry customer calls", you can say "sorry, upgrade to v3".

That's certainly another good point.


Repenning, Jack

unread,
Jun 18, 2013, 8:19:19 PM6/18/13
to api-...@googlegroups.com
On Jun 18, 2013, at 5:09 PM, Kijana Woodard <kijana....@gmail.com> wrote:

If it's a certain type of breaking change, then the old version might be immediately DOA anyway. Then what?

Then, if nothing else, version numbering gives you a way to enforce it, and even return useful information (in the 404 response to your decommissioned v1 end-point).

I suppose it preserves the root url for when you've really decided that your current efforts have no future, i.e.
vs

I think these two are pretty equivalent. I would call either one "versioning," and would expect the same benefits and costs.

"Versioning" can also be done by "Accept:" headers and versioned Content-Type names. This allows some things inaccessible by either of the above two versions, such as

 * per-resource versioning
 * clients can say "I can handle v1, v2, or v3"

But it seems to me that this is too much complexity for something reserved as a last resort anyway.


Mike Schinkel

unread,
Jun 18, 2013, 8:20:08 PM6/18/13
to api-...@googlegroups.com
On Jun 18, 2013, at 8:09 PM, Kijana Woodard <kijana....@gmail.com> wrote:
So what does a version number mean?
Things change all the time and it's no big deal, but every now and then, oops, move to v2?
If it's a certain type of breaking change, then the old version might be immediately DOA anyway. Then what?

Mark Nottingham explains it really well (I posted this link earlier in the thread too):


Abhijit Tambe

unread,
Jun 18, 2013, 8:27:16 PM6/18/13
to api-...@googlegroups.com
Can someone provide a reasonably real example of a backward-incompatible change that would require versioning?


Kevin Swiber

unread,
Jun 18, 2013, 8:43:20 PM6/18/13
to api-...@googlegroups.com
Adding to this...

API changes aren't always optional.

I've built a lot of software for businesses that must comply with legal changes.

When your resource suddenly requires a "patient consent" field or your business gets fined by the government, a new version must roll out.

Of course, this comes with proper communication in B2B and B2C channels. It's a big effort that requires human beings. Auto-upgrade is not always feasible.

Sent from my iPhone

Kevin Swiber

unread,
Jun 18, 2013, 8:55:09 PM6/18/13
to api-...@googlegroups.com
Any business domain impacted by legislation will experience backwards-incompatible change requests.  Financial, health, insurance, etc.

"We now need to include comments whenever a change occurs to a loan document or we will receive a violation when we are audited. This goes for our B2B partners, as well."

Breaking change.  API and client updates are required.

Sent from my iPhone

Kijana Woodard

unread,
Jun 18, 2013, 8:57:32 PM6/18/13
to api-...@googlegroups.com
I wish I had read that first since he brought up many of the same ideas I did, just better.

"I think these two are pretty equivalent."

Right. So why do we need to bake in versioning at the beginning as a "get out of jail free card" when, some unknown time in the future, we can just tell everyone to use blue.api.example.com?

Since, with hypermedia apis, the root is the entry point, I sort of prefer the subdomains anyway.

"Then, if nothing else, version numbering gives you a way to enforce it, and even return useful information (in the 404 response to your decommissioned v1 end-point)."

Why couldn't you return 400 with the appropriate error info, which you'd need to do anyway?

"If you're actually building the API underneath a web app you also build..."
"If you're building an API under a downloaded/installed app, still under your control..."

At this point, I control enough to make whatever decision as painless as it can be.

Note: I'm not arguing that hypermedia backwards compatibility is some silver bullet. I'm just not convinced that version numbers add any additional positive value over the negative value they introduce (e.g. big bang upgrades for clients).



Abhijit Tambe

unread,
Jun 18, 2013, 9:08:49 PM6/18/13
to api-...@googlegroups.com
I agree that this is a backward-incompatbile change (addition of one or more mandatory fields), but how does versioning help us in this scenario? Wouldn't your server still need to support the older version?

Mike Schinkel

unread,
Jun 18, 2013, 9:10:34 PM6/18/13
to api-...@googlegroups.com
On Jun 18, 2013, at 8:57 PM, Kijana Woodard <kijana....@gmail.com> wrote:
Right. So why do we need to bake in versioning at the beginning as a "get out of jail free card" when, some unknown time in the future, we can just tell everyone to use blue.api.example.com?

Probably only consistency thus establishing an easier pattern to remember and guess.  If the first one is here:

And you have a policy of infrequent changes then the next obvious version is here:


But nothing says you can't do this if it makes you happier:


-Mike

Kevin Swiber

unread,
Jun 18, 2013, 9:15:56 PM6/18/13
to api-...@googlegroups.com
Clients can be weaned off the old version and on to the new. Offenders can be discovered via access metrics prior to the government mandate. On the "cut off" day, the switch can be flipped with confidence and hopefully no downtime for clients.

Sent from my iPhone

Abhijit Tambe

unread,
Jun 18, 2013, 9:25:39 PM6/18/13
to api-...@googlegroups.com
This can be handled directly in your service without having to introduce any form of versioning. Introduce the fields as optional with a cut-off date for when they become mandatory.

I think other discussions in this thread have covered why resource-level versioning becomes unwieldy very fast. Introducing interface-level versioning seems like overkill for the case that you described.

Introducing optional fields and then having a cut off date seems much more light-weight for both clients and servers.

Repenning, Jack

unread,
Jun 18, 2013, 9:35:26 PM6/18/13
to api-...@googlegroups.com
On Jun 18, 2013, at 5:57 PM, Kijana Woodard <kijana....@gmail.com> wrote:

Note: I'm not arguing that hypermedia backwards compatibility is some silver bullet. I'm just not convinced that version numbers add any additional positive value over the negative value they introduce (e.g. big bang upgrades for clients).

So far as I can see, the versioning strategy you seem to prefer (change the hostname) is functionally equivalent to the one I've used (change the URL path). They're going to change under exactly the same circumstances, and that's going to cause exactly the same disruption. They both support equivalent supporting strategies like "run two side by side." 

In my favorite web framework (Rails), doing it i n the URL path (/api/v1 -> /api/v2) is a somewhat more localized change, easier to manage. YMMV. But they're at least 99 44/100% the same thing.



mca

unread,
Jun 18, 2013, 9:40:31 PM6/18/13
to api-...@googlegroups.com
http://blog.tojicode.com/2013/06/a-tale-of-two-web-technologies.html?showComment=1371605602954#c2359382555491358783

"Backward compatibility is what binds us most. It is deeply engrained in the Web, and in the Internet (see Postel's Law and my corollary). "
and
"...the evolutionary system doesn't care about "perfect", it cares only about "better and backward-compatible enough..."

Kevin Swiber

unread,
Jun 18, 2013, 9:52:54 PM6/18/13
to api-...@googlegroups.com
Note: Real legislation compliance is often much more complicated than the introduction of a single required field.

Even so...

The reasons why I'd opt for a new hostname in this scenario have little to do with API design.

1. The important changes have time to mature to mostly bug-free.
2. The cutover becomes an ops change, which in this case feels like less of a risk than a development change.
3. Less people have to work on the weekend, and the team is happier.

In general, I think too much emphasis is put on this topic. It's easy to bikeshed. Every situation has a unique set of circumstances.

Business software evolves with business change. The volatility of the latter impacts the volatility of the former.

There is no broad brush answer to this question.

Sent from my iPhone

Kijana Woodard

unread,
Jun 18, 2013, 9:57:55 PM6/18/13
to api-...@googlegroups.com
I agree they are the same. 

It's not really my preferred approach. I just introduced that as a way not to have to worry about versioning up front. 

In either case, I don't see how it _solves_ the problem. For a "must move" change, the old clients are still broken. I'm not seeing the huge win over @abhitit's suggestion of "Introduce the fields as optional with a cut-off date for when they become mandatory.", even if the cut-ff date is "right now".

It seems everyone agrees backwards compatibility is ideal.
In fact, it's so ideal that we will do it often enough to make version changes "rare".

In the case where we really just have to break backwards compatibility, how are version numbers superior to any other solution? Old clients are dead if they don't upgrade "in time".

I'm thinking that v2 is may be too much of a crutch. I can see it turning into "better get all your breaking changes in now because who knows when v3 is coming".


Mike Schinkel

unread,
Jun 18, 2013, 10:02:48 PM6/18/13
to api-...@googlegroups.com
On Jun 18, 2013, at 9:52 PM, Kevin Swiber <ksw...@gmail.com> wrote:
> In general, I think too much emphasis is put on this topic. It's easy to bikeshed. Every situation has a unique set of circumstances.

Great point!

-Mike

Peter Monks

unread,
Jun 18, 2013, 10:10:20 PM6/18/13
to api-...@googlegroups.com
Recall that multiple versions may be provided in parallel for some period of time - that period could range from "short" (e.g. sudden regulatory change) to "forever" (e.g. we have a high value client that is unwilling/unable to upgrade).

And you're quite right that this doesn't solve the problem, but what it does do is buy time for a graceful transition period.  It also lets clients upgrade at their leisure during this time, without forcing coordination with the API provider.  This is a major benefit vs the "modify in place and hope everyone got the memo" approach.

Cheers,
Peter

 
 

Kijana Woodard

unread,
Jun 18, 2013, 10:19:07 PM6/18/13
to api-...@googlegroups.com
I get it. I'm just not convinced.

Especially if v2 becomes a "breaking change party", if I want to update one small aspect, I have to take on the whole upgrade to move at all. Having the version number takes the pressure off of everyone from developers through management to introduce such changes which translates into pain for consumers. By having a "changes must be backwards compatible policy" it forces everyone to think carefully before they add to the api (since they will have to live with it) and before they break backwards compatibility (because they will have to deal with it). 

Straining backwards compatibility to the limit means that very few memos are required.

If it's a theoretical sudden change, no approach saves clients who didn't get the memo. They have to change code or they stop working.

As to high value client - fork. Which is essentially what running v1 in the face of v9 is anyway.

Kijana Woodard

unread,
Jun 18, 2013, 10:23:21 PM6/18/13
to api-...@googlegroups.com
BTW, the reason I think v2 becomes a "breaking change party" is because backwards compatibility is hard.

In the face of deadlines and better things to do, how many devs/pms/managers/execs _won't_ take v2 as a chance to "save time" on all the extra work compatibility requires?

Peter Monks

unread,
Jun 19, 2013, 12:24:32 AM6/19/13
to api-...@googlegroups.com
Compromises (for whatever reason) are a given, regardless of the approach.  They're less painful with versioning however, since clients can upgrade at their leisure (unlike when faced with a "breaking changes in place party").

The key element that you might be missing is that versioning doesn't actually solve any of these kinds of problems - all it does is temporally decouple the release of these types of changes from their impact on clients.

sune jakobsson

unread,
Jun 19, 2013, 3:19:49 AM6/19/13
to api-...@googlegroups.com
TL;DR Avoid versioning if you can, but if not stick the version in the URL.

So that http://api.example.com/messaging/v1/ and http://api.example.com/messaging/v2/ can both be found at http://api.example.com/messaging/ and then the client can decide if the API supports what is needed.

Sune

Mike Kelly

unread,
Jun 19, 2013, 4:06:53 AM6/19/13
to api-...@googlegroups.com

You can't build a serious m2m API  without some form of versioning strategy. Automated clients have to couple to some set of things in your application, and those things will eventually need to be changed in a breaking way... such is the nature of automated clients and application-things. It has to be dealt with.

There isn't really anything about REST or hypermedia which prevents you from employing a versioning strategy.

Where hypermedia can help is in providing the basis for developing a flexible, granular versioning strategy.

I'll describe what this might look like with HAL, because that's what I know:

In a HAL based API your clients transition over links, those links are selected (primarily) by their link relation. A link relation is itself a URL which should point to some description document that tells developers what to expect from the resource at the other end of the link (what methods, headers, properties, etc). This means that your application and its documentation has a natural granularity to it (i.e. broken down by link relations).

This can then form the basis of your strategy: which is not to version by media type or URL prefix, but to do it using link relations.

So if the behaviour for a given link changes in a non-breaking way (e.g. an additional _optional_ parameter is allowed in a POST request) then the link relation document can be updated accordingly and everything still works fine (because the change was non breaking).

And if the behaviour of a given link  needs to change in a breaking way, then a new link relation should be created. This new link relation can run in parallel to the old one for as long as necessary , and in hal it can be marked as deprecated (which should cause a compliant hal client to log a warning that its traversing a link that's being deprecated).

The overall effect of this kind of strategy is that you can manage change in your API on a granular basis (i.e. per link) which enables a more gradual evolution of the API over time through small changes instead of in big releases. This is easier to manage and carries lower risk. Its the same ideas underlying lean, agile, continuous delivery, etc.

So I don't think versioning is unnecessary but I do think that there are better ways of doing it than URL prefixes or media types.

The alternative doesn't have to be "over-architected" either, provided we don't get carried away with kitchen sink hypermedia designs that are unnecessarily complicated.

I would like to think hal+json is a good start.. There's almost 300 people in hal-discuss and a tonne of libraries for it now so I guess it must be in the right ball park! :)

Cheers,
M

Philip Nelson

unread,
Jun 19, 2013, 7:22:11 AM6/19/13
to api-...@googlegroups.com

In the case where we really just have to break backwards compatibility, how are version numbers superior to any other solution? Old clients are dead if they don't upgrade "in time".

So, there is a time period, no matter how you choose to version and retire some piece of data or action, that the client needs to react to. Could another solution be a date as part of the resource or link, generally not there, but when it is there it signals not just that it will retire, but when? I like the date better because in the workflow of maintaining your software, you are actually being a lot more specific. The api can email the team to say, uh oh, the bell tolls for this on this date. 

So rather than "I'm at version one, be happy and ignore later versions" instead it's "I am at the current version, because there is no deprecation date". Later, the api consumer's team has to take action because a deprecation date exists. Later, you may provide a resource or link of the same name/rel both with and without a deprecation date. Later, the new version without the deprecation date is the only one that exists. With hypermedia the urls are not static, so if you need to put on cruft to use your frameworks routing, you can but you still would have given a client a way to choose between specific actions or resources, just chose the one with a date if there are multiple choices. 

I am going to experiment with this, I'm probably missing something obvious, but this has been a great discussion to witness. Maybe part of the problem we have is that the only way most frameworks have to evaluate which block of code to execute is the totally deterministic route functionality it provides gives so few options. I agree that the hypermedia folks have provided precious few working examples, but the use of a state machine to determine what to do next is pretty useful thing and gives you more options than directly routing a url to a block of code. Or would if we weren't so bad at doing state machines. 

Mike Kelly

unread,
Jun 19, 2013, 7:45:27 AM6/19/13
to api-...@googlegroups.com

Originally I has intended to use a date for  hal's deprecation property but instead opted for a URL value which can then offer more detail about about the deprecation (including but not limited to the due date). I'm not sure the date on its own is hugely actionable information for a client library, so I prefer this approach.

http://tools.ietf.org/html/draft-kelly-json-hal-05#section-5.4

Any good?

--

Philip Nelson

unread,
Jun 19, 2013, 7:53:00 AM6/19/13
to api-...@googlegroups.com
I think it is very good, even more detail to help the api consumer team understand what is happening. 

Bah, I hadn't read all the way to the bottom of the thread to see your response before I sent mine. But the granularity you mention is what is key here. With HAL, and the api I'm building to push my hypermedia understanding is built on HAL, you really can just say this one thing is going to go away, and when. 

Repenning, Jack

unread,
Jun 19, 2013, 12:56:42 PM6/19/13
to api-...@googlegroups.com
On Jun 18, 2013, at 6:57 PM, Kijana Woodard <kijana....@gmail.com> wrote:

In the case where we really just have to break backwards compatibility, how are version numbers superior to any other solution? Old clients are dead if they don't upgrade "in time".

No one is arguing that any of the ideas discussed transforms "we really just have to break backwards compatibility" into "clients aren't broken." That would be a logical contradiction.

We are, rather, exploring various ways to enumerate and reduce the costs of such changes. Kevin's recent list is a fine, clear example:

The reasons why I'd opt for a new hostname in this scenario have little to do with API design.

1. The important changes have time to mature to mostly bug-free.
2. The cutover becomes an ops change, which in this case feels like less of a risk than a development change.
3. Less people have to work on the weekend, and the team is happier.

Or, as I once said, a long time ago in a thread now far far away (though it was actually this very one), "these seem really to be questions about your framework." Some interesting questions: how is it source-controlled, changed, deployed, and retired?  Your versioning strategy may well depend more on these than on subtle details of the API itself.

CJunge

unread,
Jun 20, 2013, 12:57:12 AM6/20/13
to api-...@googlegroups.com
I know it's a provisional header, but I'm surprised no-one has mentioned Accept-Datetime.

It's purpose it to allow accessing versioned content by date. Which is the same (to me at least) as accessing versioned resources from an API.

In a project I'm working on, we're using it to allow the server to decide what version of a resource is returned to a client. It allows the server to control what is returned to whom, and it's a per resource thing, so individual resources can be changed without having to create a completely new revision of the whole API. If a BC change is made that is MANDATORY, then the client is given a 406 Not Acceptable with a message indicating why if they fail to be up-to-date enough. It also makes it simpler for the client, as they just need to store a date to indicate that they were compatible at that time when it was tested.

Cameron.


On Tuesday, June 18, 2013 1:09:58 AM UTC+12, Rohit Goyal wrote:

We are creating a REST API that will be used by many consumers. For version, we decided to use Accept header. Consumer sends requested version in Accept header (application/json,version=1.0). As part of first API, we introduced 30 resources, all tagged as version 1.0

Now we putting standards on how the version-ing of API will work

1) If we change in any resource which is transparent to consumer, we call that minor version. Consumer will still send the same version (say 1.0) which internally will be routed to correct version of resource. When I say correct version of resource, I meant that we maintain a technical version for each resource and at the entry point, we map incoming API version to technical version. So consumer will still send the request with 1.0 which will be internally routed to 1.x technical version of the resource. 

2) If a change is not transparent to consumer, we call that major change. In this case consumer has to send the new decided version with request. 

Here the problem comes...

Say we had 30 resources, all tagged as 1.0. We changed 2 resources which considered as major change, for that we asked consumer to send the new version, lets say 2.0
But all other 28 resources are not changed. But because now consumer has moved to new major version of API (2.0), the unchanged resource should respond with 2.0 as well.
(Imp point to note here that consumer always rely on one major version. It's not possible that consumer send 1.0 for few resources and 2.0 for few others. If consumer moves to 2.0, all resources under the API should respond with 2.0)

To respond unchanged 28 resources work with 2.0, we are considering 2 options
1) Create copy for all 28 resources. That way we will have separate implementation for all resources comes under 2.0. It require lot of efforts everytime and go against the re-usability principal

2) Reuse existing ones. At the entry we decide that if incoming is 2.0 and matches the URI of unchanged resource, route to existing one. 

which you guys think is good to go with? Any other approach/suggestion?

Thanks
Rohit 

Austin Wright

unread,
Jun 20, 2013, 8:15:04 PM6/20/13
to api-...@googlegroups.com
The problem that you're facing is you created a new media type (specifically, a specialization of an existing media type) even though, when specializing the type, you probably wanted 30 different media types, so you can distinguish one media type from another in the headers, without needing to examine the URI: Since URIs are opaque, clients must not need to examine the URI to determine what the request means, except that it identifies a single resource being acted on, and how to deference it (access it over the network).

While versioning the media type is a good idea, inventing a media type parameter probably was not; a better media type would probably be "application/vnd.examplecorp.v1+json" (explicitly identifying a vendor-specific media type).

There's two solutions:

If you can determine one resource apart from the other 29 by looking at the entity body (e.g. if there's a {"type":"item"} statement somewhere), then keep considering the document as a single media type, and update it to "2.0". Your server should understand that the format for v2 versions for these 28 resources are identical to the v1 version.

Otherwise, adopt a media type parameter that uniquely identifies the media type that _you_ are using. For instance, use:

Content-Type: application/json;profile="http://example.com/v1/item"

And again this URI is opaque, it could just as well also be <http://example.com/item.1.0.json>

Mike Schinkel

unread,
Jun 20, 2013, 9:20:11 PM6/20/13
to api-...@googlegroups.com
On Jun 20, 2013, at 8:15 PM, Austin Wright <diamon...@users.sourceforge.net> wrote:
The problem that you're facing is you created a new media type (specifically, a specialization of an existing media type) even though, when specializing the type, you probably wanted 30 different media types, so you can distinguish one media type from another in the headers, without needing to examine the URI.

Here's an approach I have been considering for a while, and that's in a context like Rohit described: Create one new media type i.e. "application/vnd.examplecorp.v1+json" and then to design it so that it can address all 30 different use-cases.

If you look at HTML, it works the same way.  HTML can have a list of images, or it can have a document with headings and paragraphs; it all depends on which elements to use; the combinations are almost infinite. 

So rather than this:

application/json;profile="http://example.com/v1/item"

Why not this:

application/vnd.examplecorp.v1+json

And then have the file contain an "item" as the root property of the element? i.e.:

{ "item": {...} }

Other instances of the same media type could start like this:

{ "person": {...} }
{ "people": {...} }
{ "orders": {...} }
{ "items": {...} }
etc.

JSON can have optional properties so why not define a media type for an entire problem domain instead of one specific use-case in that problem domain?

Granted, I've not proven this concept yet so it may have flaws, but from studying the main example given as a working example of hypermedia it seems there is precedent for it...


-Mike

Austin Wright

unread,
Jun 20, 2013, 11:09:34 PM6/20/13
to api-...@googlegroups.com

On Thursday, June 20, 2013 6:20:11 PM UTC-7, mikeschinkel wrote:
Here's an approach I have been considering for a while, and that's in a context like Rohit described: Create one new media type i.e. "application/vnd.examplecorp.v1+json" and then to design it so that it can address all 30 different use-cases.


If you look at HTML, it works the same way.  HTML can have a list of images, or it can have a document with headings and paragraphs; it all depends on which elements to use; the combinations are almost infinite. 

So rather than this:

application/json;profile="http://example.com/v1/item"

Why not this:

application/vnd.examplecorp.v1+json

And then have the file contain an "item" as the root property of the element? i.e.:

{ "item": {...} }

Other instances of the same media type could start like this:

{ "person": {...} }
{ "people": {...} }
{ "orders": {...} }
{ "items": {...} }
etc.

JSON can have optional properties so why not define a media type for an entire problem domain instead of one specific use-case in that problem domain?

Granted, I've not proven this concept yet so it may have flaws, but from studying the main example given as a working example of hypermedia it seems there is precedent for it...

-Mike

Right, that's pretty much my first suggestion. While it works as a solution, I don't prefer it: it adds coupling (generic user agents won't understand the media type) and forces you to look at the entity body (while not outright wrong, it is more costly than just looking at the Content-Type header, you're essentially sending a response no different than a multipart/form-data response).

Additionally, I just like URIs. It says that there's a globally unique name for the particular vocabulary deployed in the JSON, which allows you to talk about your particular format at the same time you talk about third party JSON formats. The more specific you can get in distinguishing the media types, the better. And you can serve a JSON Schema at that URI and clients can use to extract hyperlinks from the JSON, and humans can read it to see descriptions and labels. All around it's just far friendlier to generic user agents, or people writing API mash-ups.

Austin.

Mike Schinkel

unread,
Jun 20, 2013, 11:57:34 PM6/20/13
to api-...@googlegroups.com
On Jun 20, 2013, at 11:09 PM, Austin Wright <diamon...@users.sourceforge.net> wrote:
Right, that's pretty much my first suggestion. While it works as a solution, I don't prefer it: it adds coupling (generic user agents won't understand the media type) and

If I'm not mistaken, Roy Fielding argues for REST against generic media types that can be understood by generic user agents.  My interpretation of his post and comments[1] are that he advocates for user agents that have in-built understanding of the media type and that everything needed for the client to know how to process it is found in the media type definition and he also argues that the number of media types should be small.

Of course if you are arguing for an architecture that is explicitly not REST then please ignore the preceding paragraph. 

forces you to look at the entity body (while not outright wrong, it is more costly than just looking at the Content-Type header, you're essentially sending a response no different than a multipart/form-data response).

Forces you for what purpose?  Can you describe a use-case where this is going to be a big concern? Has it been a big issue with HTML? And if you are going to process the body why is it an issue to have to look into the body?

From Roy[1]:

REST is software design on the scale of decades: every detail is intended to promote software longevity and independent evolution. Many of the constraints are directly opposed to short-term efficiency.

Are you more concerned about short-term efficiency? Which is valid if you are, but its not REST.

Additionally, I just like URIs.

I like them too, but only when they are called URLs. :) 

OTOH URLs are not needed for everything, especially when they add unnecessarily recurring complexity.  For example, who can remember the full valid URLs for the different HTML 4 DOCTYPE declarations? I sure as hell have never been able to.  Fortunately sanity prevailed with "<!DOCTYPE HTML>" for HTML 5.

It says that there's a globally unique name for the particular vocabulary deployed in the JSON, which allows you to talk about your particular format at the same time you talk about third party JSON formats. The more specific you can get in distinguishing the media types, the better.

If you define a specific media type and register it with IANA you get to distinguish the media type exactly.  And even if you don't register it you can include a link to documentation as an X-{header} or in the body or if you like.

And you can serve a JSON Schema at that URI and clients can use to extract hyperlinks from the JSON, and humans can read it to see descriptions and labels. All around it's just far friendlier to generic user agents, or people writing API mash-ups.

Use of JSON Schema, while viable creates so much complexity that I question the wisdom of building an architecture that requires it. I don't think HTML would have been successful enough to for the web to explode in usage if HTML was a meta document. XML is like HTML+meta and while XML is widely used for Enterprise use-cases it requires a order of magnitude more skill to work with it when it starts including namespaces and that means fewer people can work with it. 

I'm arguing the same is true if you have to use JSON Schema with JSON. Great for Enterprise applications where they can afford perfection and are not concerned with the scale of decades  but not so good at following Postel's law which IMO is an significant reason of why the web has worked.

But, YMMV of course. :)

-Mike


Austin Wright

unread,
Jun 21, 2013, 6:31:29 AM6/21/13
to api-...@googlegroups.com

On Thursday, June 20, 2013 8:57:34 PM UTC-7, mikeschinkel wrote:

If I'm not mistaken, Roy Fielding argues for REST against generic media types that can be understood by generic user agents.  My interpretation of his post and comments[1] are that he advocates for user agents that have in-built understanding of the media type and that everything needed for the client to know how to process it is found in the media type definition and he also argues that the number of media types should be small.

Of course if you are arguing for an architecture that is explicitly not REST then please ignore the preceding paragraph. 

A generic media type is one that any user agent can use, e.g. HTML, or JSON. Inventing your own media type, e.g. application/vnd.examplecorp+json, introduces coupling (an interface specific to your API) which is very not-RESTful and something that Roy argues against in that blog post. Requiring specialized knowledge specific to your API is what is bad.

A media type of e.g. application/json;profile=http://example.com/v1/post.json is generic so that a robot or other user agent can make use of the endpoint, while at the same time indicating which vocabulary it uses so that it may be used in an RPC fashion. That is to say, it properly identifies that the content being returned is a subset of application/json, and so the user agent knows it can apply application/json behavior, as well as whatever other behavior it knows is specific to the specified profile, if any.

Also note none of the solutions we are talking about were necessarily RESTful to begin with. The only one here I've seen (pardon my skimming through many of the posts) would be my suggestion to utilize JSON Hyper-Schema, thus satisfying the hypertext constraint.
 

forces you to look at the entity body (while not outright wrong, it is more costly than just looking at the Content-Type header, you're essentially sending a response no different than a multipart/form-data response).

Forces you for what purpose?  Can you describe a use-case where this is going to be a big concern? Has it been a big issue with HTML? And if you are going to process the body why is it an issue to have to look into the body?

It's a concern for efficiency, and the reason the client-server constraint exists in REST. You should be able to figure out which internal path to route the data stream to by looking at the headers, without needing to buffer an uploaded file in memory, then parsing it, then routing it to the appropriate function. Routing data is metadata, and it doesn't belong in the entity-body (or at least not exclusively).

This issue doesn't come up in HTML because people don't typically use HTML for their APIs. Those who do will find themselves running up against the same problem. My arguments apply equally to all media types.
 

From Roy[1]:

REST is software design on the scale of decades: every detail is intended to promote software longevity and independent evolution. Many of the constraints are directly opposed to short-term efficiency.

Are you more concerned about short-term efficiency? Which is valid if you are, but its not REST.

None of our solutions were (completely) RESTful to begin with, and this point doesn't uniquely impact my proposal any more than anyone else's.

If you want all the benefits you're discussing, you're going to have to use HTML.
 

Additionally, I just like URIs.

I like them too, but only when they are called URLs. :) 

OTOH URLs are not needed for everything, especially when they add unnecessarily recurring complexity.  For example, who can remember the full valid URLs for the different HTML 4 DOCTYPE declarations? I sure as hell have never been able to.  Fortunately sanity prevailed with "<!DOCTYPE HTML>" for HTML 5.

You're not supposed to memorize them, they're there for the benefit of machines. Now we have no way of differentiating HTML from other vocabularies, except doing so in a media type. This isn't such a bad thing for user agents speaking HTTP or MIME, but it very much impacts writing files to a filesystem, among other things (not something we're concerned with in this API, or is otherwise easily mitigated). (And unfortunately some of the recent editors seem to think the only kind of user agent that will ever use HTML are Web browsers.)
 
If you define a specific media type and register it with IANA you get to distinguish the media type exactly.  And even if you don't register it you can include a link to documentation as an X-{header} or in the body or if you like.

But again, a custom media type becomes inaccessible to generic user-agents. Try serving a webpage as text/vnd.example+html, see what happens. It loses its status as hypertext. You've now reduced an HTTP API to a mere RPC.

Use of JSON Schema, while viable creates so much complexity that I question the wisdom of building an architecture that requires it. I don't think HTML would have been successful enough to for the web to explode in usage if HTML was a meta document. XML is like HTML+meta and while XML is widely used for Enterprise use-cases it requires a order of magnitude more skill to work with it when it starts including namespaces and that means fewer people can work with it. 

I never said any application should require JSON Schema, just that you can serve a JSON Schema at the (otherwise opaque) profile URL, to the benefit of generic user agents: A generic user agent, if aware of a JSON Schema that describes a JSON response, automatically generate an editable form and process and present Link relations. This supports the REST notion that the server and client can independently evolve.

Austin.

Mike Kelly

unread,
Jun 21, 2013, 7:38:25 AM6/21/13
to api-...@googlegroups.com
>> fewer people can work with. it
>
>
> I never said any application should require JSON Schema, just that you can
> serve a JSON Schema at the (otherwise opaque) profile URL, to the benefit of
> generic user agents: A generic user agent, if aware of a JSON Schema that
> describes a JSON response, automatically generate an editable form and
> process and present Link relations. This supports the REST notion that the
> server and client can independently evolve.

This is theoretically possible, but in my experience most developers
are just looking for human readable explanation of the potential
requests that can be made on a given resource, and they want to test
those requests close to the wire in order to simulate the activity of
the integrating code they're going to write i.e. not via the
indirection of a GUI form. I suspect this is why people like the HAL
browser.

Cheers,
M

Mike Schinkel

unread,
Jun 21, 2013, 3:01:13 PM6/21/13
to api-...@googlegroups.com
On Jun 21, 2013, at 6:31 AM, Austin Wright <diamon...@users.sourceforge.net> wrote:
A generic media type is one that any user agent can use, e.g. HTML, or JSON. Inventing your own media type, e.g. application/vnd.examplecorp+json, introduces coupling (an interface specific to your API) which is very not-RESTful and something that Roy argues against in that blog post. Requiring specialized knowledge specific to your API is what is bad.

A media type of e.g. application/json;profile=http://example.com/v1/post.json is generic so that a robot or other user agent can make use of the endpoint, while at the same time indicating which vocabulary it uses so that it may be used in an RPC fashion. That is to say, it properly identifies that the content being returned is a subset of application/json, and so the user agent knows it can apply application/json behavior, as well as whatever other behavior it knows is specific to the specified profile, if any.

I've read and re-read Roy's post and comments so many times that I'm 99% sure that the above is actually contrary to what is RESTful (oh how I wish Roy was on this list so he could explain what he meant instead of me trying my best in earnest.)  

But it took a long time for me to develop my current understanding; I previously thought Roy meant as you explained. But I was left with inconsistencies and my current understanding resolves those inconsistencies.  Let's see if I can quote Roy[1] in order of his post to clarify (any emphasis mine):

Roy: A REST API should not contain any changes to the communication protocols aside from filling-out or fixing the details of underspecified bits of standard protocols, such as HTTP’s PATCH method or Link header field. Workarounds for broken implementations (such as those browsers stupid enough to believe that HTML defines HTTP’s method set) should be defined separately, or at least in appendices, with an expectation that the workaround will eventually be obsolete. [Failure here implies that the resource interfaces are object-specific, not generic.]

Me: This potentially implies that "Profile" is one such workaround although I'm not certain of this interpretation.

Roy: A REST API should never have “typed” resources that are significant to the client. Specification authors may use resource types for describing server implementation behind the interface, but those types must be irrelevant and invisible to the client. The only types that are significant to a client are the current representation’s media type and standardized relation names.[ditto]

Me: This is where the generic media type failed the RESTful test and why specific media types are RESTful.  My using a generic media type with data that is not defined in that media type's representation you are "typing" a resource, which is no-no.  I'm not sure but I believe the use of a profile and/or JSON schema both attempt to "type" generic media types.

Roy: A REST API should be entered with no prior knowledge beyond the initial URI (bookmark) and set of standardized media types that are appropriate for the intended audience (i.e., expected to be understood by any client that might use the API). From that point on, all application state transitions must be driven by client selection of server-provided choices that are present in the received representations or implied by the user’s manipulation of those representations. The transitions may be determined (or limited by) the client’s knowledge of media types and resource communication mechanisms, both of which may be improved on-the-fly (e.g., code-on-demand). [Failure here implies that out-of-band information is driving interaction instead of hypertext.]

Me: This explicitly discredits the assertion that "Inventing your own media type  introduces coupling which is very not-RESTful and something that Roy argues against in that blog post."  It is coupling, but according to Roy's it is good coupling. There will be more on this below.

Roy: To some extent, people get REST wrong because I failed to include enough detail on media type design within my dissertation. That’s because I ran out of time, not because I thought it was any less important than the other aspects of REST. 

Me: Here Roy is putting an emphasis on media types. This imply Roy's focus on media types, not a belief that media types introduce (bad) coupling. There will be more on this below.

Roy: Automated agents are dependent on their understanding of the media types, link types, or microformat extensions provided in representations. It is the same basic issue as with human communication: we will always need a common vocabulary to make sense of it. Exposing that vocabulary in the representations makes it easy to learn and be adopted by others. Some of it will be standardized, some of it will be domain-specific, but ultimately the agents will have to be adaptable to new vocabulary.

Me: We are starting to get to the smoking gun.  Here Roy is saying that clients need to have knowledge of the media type and that is what you (I think mistakenly) say is non-RESTful. Instead I believe Roy is saying that it is exactly RESTful.

Roy: Every media type defines a default processing model. For example, HTML defines a rendering process for hypertext and the browser behavior around each element. It has no relation to the resource methods GET/PUT/POST/DELETE/… other than the fact that some media type elements will define a process model that goes like “anchor elements with an href attribute create a hypertext link that, when selected, invokes a retrieval request (GET) on the URI corresponding to the CDATA-encoded href attribute.” Identifiers, methods, and media types are orthogonal concerns — methods are not given meaning by the media type. Instead, the media type tells the client either what method to use (e.g., anchor implies GET) or how to determine the method to use (e.g., form element says to look in method attribute). The client should already know what the methods mean (they are universal) and how to dereference a URI.

Me: Here it gets even more clear that Roy is saying that the client needs to be coupled to an understanding of the media type.

Roy: The interface doesn’t need to be discovered. It is defined right there in the hypertext. The representation tells the client how to compose all transitions to the next application state. This could be as simple as an anchor or as complex as a java applet. 

Me: Here I believe Roy is saying that a client should not (need to) use external schemas (or profiles) to discover how to process a media type but instead that a client should fully understand the media type. Indeed, that's the whole point of a media type; to enable to client that see the media type string in the Content-type header to be able to say "Oh, I know that is and I know exactly what I need to do to process it."  Using a generic media type and processing it specifically with or without an externally discoverable interface is thus not RESTful.

Roy: HTML doesn’t need type specifications. No RESTful architecture needs type specifications. Don’t expect REST to act like some other architectural style. You don’t get to decide what POST means — that is decided by the resource. Its purpose is supposed to be described in the same context in which you found the URI that you are posting to. Presumably, that context (a hypertext representation in some media type understood by your client) tells you or your agent what to expect from the POST using some combination of standard elements/relations and human-readable text. 

Me: Here it gets even more clear that 1.) using a schema (and maybe even a profile) is not RESTful, and clients should have in-built understanding of the media types they process.

Roy: Of course the client has prior knowledge. Every protocol, every media type definition, every URI scheme, and every link relationship type constitutes prior knowledge that the client must know (or learn) in order to make use of that knowledge. REST doesn’t eliminate the need for a clue. What REST does is concentrate that need for prior knowledge into readily standardizable forms. That is the essential distinction between data-oriented and control-oriented integration.

Me: And it gets ever so more clear here. A client must have prior knowledge of a media type for such a system to be consider RESTful.  This completely contradicts the assertion (that) "Inventing your own media type introduces coupling (an interface specific to your API) which is very not-RESTful and something that Roy argues against in that blog post."

Roy: In terms of testing a specification, the hardest part is identifying when a RESTful protocol is actually dependent on out-of-band information or if the authors are just overspecifying things for the purpose of documentation. What I look for are requirements on processing behavior that are defined outside of the media type specification. One of the easiest ways to see that is when a protocol calls for the use of a generic media type (like application/xml or application/json) and then requires that it be processed in a way that is special to the protocol/API. 

Me: And here I don't think it can get more explicit than this: using a generic media type like application/json is not RESTful. 

Roy: The media type identifies a specification that defines how a representation is to be processed. That is out-of-band information (all communication is dependent on some prior knowledge). What you are missing is that each representation contains the specific instructions for interfacing with a given service, provided in-band. The media type is a generic processing model that every agent can learn if there aren’t too many of them (hence the need for standards). The representation is specific to the application being performed by the agent. Each representation therefore provides the transitions that are available at that point in the application.

Me: This is what I was referring to as "Good Coupling" above. He explicitly states that clients are coupled to media types using "out-of-band-information."

Roy: That doesn’t mean that I think everyone should design their own systems according to the REST architectural style. REST is intended for long-lived network-based applications that span multiple organizations. If you don’t see a need for the constraints, then don’t use them. That’s fine with me as long as you don’t call the result a REST API. I have no problem with systems that are true to their own architectural style.

Me: And here's the qualifier; your system doesn't have to be RESTful. But when giving advice on a former where RESTfulness is often assume I think it's implies that advice should come with a disclaimer that the advice deviates from RESTfulness.

One final point about media types and that is that too many media types is just as bad as too few:

Roy: The media type identifies a specification that defines how a representation is to be processed. That is out-of-band information (all communication is dependent on some prior knowledge). What you are missing is that each representation contains the specific instructions for interfacing with a given service, provided in-band. The media type is a generic processing model that every agent can learn if there aren’t too many of them (hence the need for standards). The representation is specific to the application being performed by the agent. Each representation therefore provides the transitions that are available at that point in the application.

Me: What this means to me is that media types that can combine use-cases are better than having lots of media types because it can result in fewer media types. And ideally, there would not be one media type per vendor for a broad problem domain but a collaboration between vendors such that there is only one media type for a given problem domain.

It's a concern for efficiency, and the reason the client-server constraint exists in REST. You should be able to figure out which internal path to route the data stream to by looking at the headers, without needing to buffer an uploaded file in memory, then parsing it, then routing it to the appropriate function. Routing data is metadata, and it doesn't belong in the entity-body (or at least not exclusively).

This issue doesn't come up in HTML because people don't typically use HTML for their APIs. Those who do will find themselves running up against the same problem. My arguments apply equally to all media types.

I believe what you are referring to the need for an intermediary on the network such as a router to not have to look at the body vs. the client having to look or not look into the body. So I don't buy your routing concern as a reason to create many different media types for each use-case, at least not without a good example where you'll need to route something differently. 

What's an example of a media type crafting in the form of HTML where there are many optional elements/properties where an intermediary needs to reach in and see data that IMO only a client needs to see.  This seems to me to be abstract concern without a use-case, not a real concern.

Of course if you do find a use-case where reaching into the body for routing becomes a serious issue then go ahead and make multiple media types. But don't arguing against a single media type unless you have specific known instances of this specialized need for routing for specific problem domains. I assert that in the vast majority of cases you will not.

Anyway, back to Roy: REST is intended for long-lived network-based applications that span multiple organizations. If you don’t see a need for the constraints, then don’t use them. That’s fine with me as long as you don’t call the result a REST API. I have no problem with systems that are true to their own architectural style.

Me: I think this is pretty clear that REST is not about efficiency.


None of our solutions were (completely) RESTful to begin with, and this point doesn't uniquely impact my proposal any more than anyone else's.

Which solutions are you reference to, explicitly?  

If you want all the benefits you're discussing, you're going to have to use HTML.

Wrong, RSS and ATOM have those same benefits, when used for their originally intended use-cases and those can be used for automated processing in addition to human processing. 

And there are probably others I don't know of or can't think of right now.

You're not supposed to memorize them, they're there for the benefit of machines.

I've heard that argument so many times and I still can't believe people make it. I remember when people use to say that users didn't need to understand URLs and yet look at how apps like Twitter have leveraged the URL to be something that most users understand and know how to deconstruct and then use the deconstructed components and/or to construct new URLs.  I think that recent history has shown that the things that have taken hold have more often than not been easily grokable by humans. It's only when businesses push employees to use complex solutions (like many of those provided by Microsoft, Oracle, SAP, etc.) that complexity is allowed to perpetuate.

If you make something that is designed for machines but not humans then fewer humans believe at first glance that they can understand it, so fewer humans ultimately try to understand it. I can't tell you how many people I've trying to teach HTML to that have struggled with those old DOCTYPEs.  And I don't know for sure how many web pages exist on the web that don't have DOCTYPEs but I can assure you its not an insignificant percentage and my assertion is that if it were easy it wouldn't be an issue.

Why has JSON overtaken XML as the representation of choice for most new web services these days?  Because it's so much easier for humans to deal with than XML is.  We can read it, there are no namespaces to have to figure out, there is limited complexity in JSON (no attributes, no namespaces, etc.) and JSON is very easy to process is most programming languages; not so with XML, because of its complexity.

Now we have no way of differentiating HTML from other vocabularies, except doing so in a media type. This isn't such a bad thing for user agents speaking HTTP or MIME, but it very much impacts writing files to a filesystem, among other things (not something we're concerned with in this API, or is otherwise easily mitigated). (And unfortunately some of the recent editors seem to think the only kind of user agent that will ever use HTML are Web browsers.)

I don't understand this concern at all.  Maybe you can give use-case examples?

But again, a custom media type becomes inaccessible to generic user-agents.

I think my long exegesis of Roy above covers why generic user-agents are not RESTful so I concern for generic user-agents in context of REST is moot.

Try serving a webpage as text/vnd.example+html, see what happens. It loses its status as hypertext. You've now reduced an HTTP API to a mere RPC.

Correct, but you are taking it in the wrong direction. If you really need text/vnd.example+html then build a client that understands it.  But that makes little sense if it is something to be consumed by users where billions of text/html user agents have been deployed.

Remember, you have been arguing for API usage so an example that modified HTML does not apply to this discussion unless you want to process as an API in which case build a media-type specific client.

I never said any application should require JSON Schema, just that you can serve a JSON Schema at the (otherwise opaque) profile URL, to the benefit of generic user agents: A generic user agent, if aware of a JSON Schema that describes a JSON response, automatically generate an editable form and process and present Link relations. This supports the REST notion that the server and client can independently evolve.

Again, not sure based on Roy that doing so is RESTful.  But I'm still learning, maybe it is?

-Mike

Austin Wright

unread,
Jun 21, 2013, 8:31:26 PM6/21/13
to api-...@googlegroups.com
Do you understand what a generic user-agent is? It's something like a web browser, or web spider or robot, that doesn't consume any particular API, and can be used to interface with _any_ supported media type, such as JSON, RSS, or HTML over HTTP.

REST is specifically designed for the benefit of these generic user agents, so that without knowing anything about what the API does, it can see hyperlinks, see declarations on how one resource relates to another, and follow those hyperlinks, as well as perform actions, like constructing a URL or a POST entity-body from a form, as specified by the server (as opposed to the client needing to understand ahead of time how to construct a POST entity-body).

A "change to the communication protocol" would be something like introducing your own HTTP method: This prohibits it so generic user agents from consuming your API. Introducing a parameter like "profile" does not change the communication protocol, it adds additional information on top of it. so that a program may interface with the API in RPC fashion. Do you see the distinction?

In Roy's language, adding the "profile" does not create a new media type, it specifies that the enclosed content-type is a subset of that media type. <http://tools.ietf.org/html/rfc2046> provides information on the semantics of media type parameters.

Now, I presented constructing your own media type as a solution to the original poster's problem. I think it is a matter of choosing the lesser of two bad paradigms, I would rather see a specific media type that has a globally unique name, than use of a media type that overloads a generic one (when one uses application/json;version=1.0 which API are we talking about? It appears as if we're talking about JSON version 1.0, which is plainly wrong.). However, there is a solution which solves both problems: Using the "profile" parameter of application/json. It provides a globally unique name that you may use to describe your API, and it uses a generic media type that generic user agents can consume.

In quotes, you bold the wrong text. It should read:

"One of the easiest ways to see that is when a protocol calls for the use of a generic media type (like application/xml or application/json) and then requires that it be processed in a way that is special to the protocol/API."

A generic media type is not only RESTful, but required (indeed, he promotes the use of HTML in APIs, as opposed to non-hypertext formats like JSON). What makes usage of a generic media type in an API not RESTful is when you require that the media type is handled in some way special to the API. This is comparable to visiting a website, and it tells you "Your web browser must treat the <pre youtube-src="..."> tag with our special provided plugin in order to play videos". This is "processed in some way special to the API", and this is not RESTful. A media type must act consistently no matter what API it is being used with.

The thing he is talking about is requiring specialized knowledge in order to interface with an API. A generic user agent like my web browser should be able to pull up a website and just use it, never having seen it before.

If you want to add special, optional behavior to your API, then fine, but that's RPC behavior on top of the RESTful part of your API.

Here I believe Roy is saying that a client should not (need to) use external schemas (or profiles) to discover how to process a media type but instead that a client should fully understand the media type. Indeed, that's the whole point of a media type; to enable to client that see the media type string in the Content-type header to be able to say "Oh, I know that is and I know exactly what I need to do to process it."  Using a generic media type and processing it specifically with or without an externally discoverable interface is thus not RESTful.

A schema is provided as a link, any generic client can follow that link, and any generic client can understand JSON Schema, and imbue the received JSON with meaning. What he is describing here is introducing application-specific behavior, like the "youtube:player" tag that I talked about.

A REST API should never have “typed” resources that are significant to the client. Specification authors may use resource types for describing server implementation behind the interface, but those types must be irrelevant and invisible to the client. The only types that are significant to a client are the current representation’s media type and standardized relation names.

The REST API I am proposing is not typed, to a REST client, it is application/json (strictly, this still isn't RESTful as JSON lacks hypertext. If the client were provided a Link header to the JSON Hyper-schema, it would become more RESTful.). To an RPC designed to couple with the API, it is `application/json;profile=http://example.com/v1/whatever.json`. Also note that he says media types and URIs are provided for the benefit of the server; the server is allowed to treat a specific media type as special, or to treat a particular URI format as special. A client is not.

Austin.

Mike Schinkel

unread,
Jun 21, 2013, 10:11:51 PM6/21/13
to api-...@googlegroups.com
On Jun 21, 2013, at 8:31 PM, Austin Wright <diamon...@users.sourceforge.net> wrote:
Do you understand what a generic user-agent is? It's something like a web browser, or web spider or robot, that doesn't consume any particular API, and can be used to interface with _any_ supported media type, such as JSON, RSS, or HTML over HTTP.

Is seems to me that "generic user-agent that doesn't consume any particular API" and "supported media" are mutually exclusive concepts.

REST is specifically designed for the benefit of these generic user agents, so that without knowing anything about what the API does, it can see hyperlinks, see declarations on how one resource relates to another, and follow those hyperlinks, as well as perform actions, like constructing a URL or a POST entity-body from a form, as specified by the server (as opposed to the client needing to understand ahead of time how to construct a POST entity-body).

It's seems clear to me that we both have our own respective understandings of what it REST and REST what is not and our understandings are apparently conflicting. Thus one of our understandings by definition must be wrong.  Either that or we are not understanding each other.

In Roy's language, adding the "profile" does not create a new media type, it specifies that the enclosed content-type is a subset of that media type. <http://tools.ietf.org/html/rfc2046> provides information on the semantics of media type parameters.

Nowhere in RFC 2046 did I find the word "profile"; instead I found this which is very similar to your quote but discussing something different (emphasis mine):

In general, the top-level media type is used to declare the general type of data, while the subtype specifies a specific format for that type of data.  Thus, a media type of "image/xyz" is enough to tell a user agent that the data is an image, even if the user agent has no knowledge of the specific image format "xyz".

So that's referring to "json" in the "application" part not a profile (which is still only a draft[1]), and further RFC 2046 is in context of MIME, not RESTful systems.  Yes HTTP uses Content-Types but RFC 2046 was written about email, not about RESTful APIs.

Lastly I don't see anywhere where Roy participated in RFC 2046 nor have I seem him advocate profiles for Content Types.  

BTW, I think James Snell has the right take on Profiles and Media Types:


In quotes, you bold the wrong text. It should read:

I bolded exactly the text I intended to bold.  The fact you would bold something else does not make my choice wrong, it's just different from your choice.

"One of the easiest ways to see that is when a protocol calls for the use of a generic media type (like application/xml or application/json) and then requires that it be processed in a way that is special to the protocol/API."

Using what you bolded, that says to me that if you process application/json in a way that recognizes any structure beyond what is defined here: http://www.ietf.org/rfc/rfc4627.txt then you are not processing it in a RESTful manner.

A generic media type is not only RESTful, but required

Please provide references where this is stated because my understanding is that use of generic media types for anything beyond what's define in their spec is not RESTful.

What makes usage of a generic media type in an API not RESTful is when you require that the media type is handled in some way special to the API. This is comparable to visiting a website, and it tells you "Your web browser must treat the <pre youtube-src="..."> tag with our special provided plugin in order to play videos". This is "processed in some way special to the API", and this is not RESTful. A media type must act consistently no matter what API it is being used with.

Reviewing this I agree.  But reading (most of) what else you've written I can't help but think that your understanding of "special to the API" is very different from my understanding of that same phrase.  To me "special to the API" means the API is using the media type in a manner that is not defined in the media type specification. Period.  

For example, in HTML there is an <a> tag and am <img> tag; the former has @href and the latter @src but while both accept URL values the browser processes those URLs differently and the browser has in-build knowledge of <a @href> vs. <img @src>.

Similar if you received a representation in the generic media type application/json like below and your client was programmed to navigate to the "href" in the "a" link then it would be doing something "special to the API" and would thus be non-restful because the JSON does not define the meaning of "a" nor "href" and especially not what the value of "cart" means for "rel": 

  "a": {
      "rel": "cart",
      "href": "http"//api.example.com/cart"
   }
}

The thing he is talking about is requiring specialized knowledge in order to interface with an API. A generic user agent like my web browser should be able to pull up a website and just use it, never having seen it before.

We are talking about media types for use with APIs; why keep bringing up browsers loading websites?

If you want to add special, optional behavior to your API, then fine, but that's RPC behavior on top of the RESTful part of your API.

How do you make the leap from optional behavior to "then it must be RPC?"

A schema is provided as a link, any generic client can follow that link, and any generic client can understand JSON Schema, and imbue the received JSON with meaning. What he is describing here is introducing application-specific behavior, like the "youtube:player" tag that I talked about.

My understanding is that creating discoverable interfaces is not what Roy intended for REST; to whit (emphasis mine):

Roy: The interface doesn’t need to be discovered. It is defined right there in the hypertext. The representation tells the client how to compose all transitions to the next application state. This could be as simple as an anchor or as complex as a java applet.
The REST API I am proposing is not typed, to a REST client, it is application/json (strictly, this still isn't RESTful as JSON lacks hypertext.

Correct, it's not RESTful. 

If the client were provided a Link header to the JSON Hyper-schema, it would become more RESTful.).

It's not RESTful according to my interpretation of Roy's statement: 

"The interface doesn’t need to be discovered. It is defined right there in the hypertext."
Also note that he says media types and URIs are provided for the benefit of the server; the server is allowed to treat a specific media type as special, or to treat a particular URI format as special. A client is not.

Agreed, but I don't see the relevance in this discussion.

-Mike

Mike Kelly

unread,
Jun 22, 2013, 4:22:33 AM6/22/13
to api-...@googlegroups.com

So... What are the actual, practical differences in evolvability between a versioning technique using profiles than one using custom media type identifiers?

Austin Wright

unread,
Jun 22, 2013, 8:26:34 AM6/22/13
to api-...@googlegroups.com

On Friday, June 21, 2013 7:11:51 PM UTC-7, mikeschinkel wrote:
Is seems to me that "generic user-agent that doesn't consume any particular API" and "supported media" are mutually exclusive concepts.

How so? A generic user agent supports media types that can be employed by any API or website. Any API, no matter what purpose it serves, can choose to use JSON Hyper-schema or HTML, and any user agent that understands that media would be able to consume it, having no other knowledge of what purpose the API does, or even if the API was invented after the user agent was. This serves the role that the client and server may independently evolve.

If your server requires that a client understand a newly invented, API-specific media type in order for it to work, then your API is not RESTful. Period. (This is the "Uniform Interface" constraint of REST.)
 

REST is specifically designed for the benefit of these generic user agents, so that without knowing anything about what the API does, it can see hyperlinks, see declarations on how one resource relates to another, and follow those hyperlinks, as well as perform actions, like constructing a URL or a POST entity-body from a form, as specified by the server (as opposed to the client needing to understand ahead of time how to construct a POST entity-body).

It's seems clear to me that we both have our own respective understandings of what it REST and REST what is not and our understandings are apparently conflicting. Thus one of our understandings by definition must be wrong.  Either that or we are not understanding each other.

In Roy's language, adding the "profile" does not create a new media type, it specifies that the enclosed content-type is a subset of that media type. <http://tools.ietf.org/html/rfc2046> provides information on the semantics of media type parameters.

Nowhere in RFC 2046 did I find the word "profile"; instead I found this which is very similar to your quote but discussing something different (emphasis mine):

In general, the top-level media type is used to declare the general type of data, while the subtype specifies a specific format for that type of data.  Thus, a media type of "image/xyz" is enough to tell a user agent that the data is an image, even if the user agent has no knowledge of the specific image format "xyz".

So that's referring to "json" in the "application" part not a profile (which is still only a draft[1]), and further RFC 2046 is in context of MIME, not RESTful systems.  Yes HTTP uses Content-Types but RFC 2046 was written about email, not about RESTful APIs.

Lastly I don't see anywhere where Roy participated in RFC 2046 nor have I seem him advocate profiles for Content Types.  

Why should Roy have to participate in RFC 2046? It's a normative reference in the HTTP spec! See <http://tools.ietf.org/html/rfc2616#section-17> and the in-line citations that link to that citation. Remember that HTTP is based off of MIME, and normatively re-uses many of its standards. There's even a dialect of HTTP that is MIME-compliant.

"profile" is a media type parameter that is added by the proposed JSON Schema standard. It is a proper employment of Media type semantics, to say not only is an information resource of a particular nature, but that it carries additional semantics. All it does is say "Hey, you understand the vocabulary I'm speaking? Great, use it to your advantage! Don't understand it? No worries, consume it as application/json just like any other!"

Additionally, it is also a Link relation type defined in <http://tools.ietf.org/html/rfc6906>. It appears you know about this from the link below, do note that the Link semantics are different than the profile parameter semantics: the "profile" parameter is not a hyperlink (yet).
 

BTW, I think James Snell has the right take on Profiles and Media Types:


In quotes, you bold the wrong text. It should read:

I bolded exactly the text I intended to bold.  The fact you would bold something else does not make my choice wrong, it's just different from your choice.

I'm pointing out that you completely ignored an essential qualifier within the statement. It's as bad quoting "A human is a criminal" but leaving out "when they steal property". The statement does not apply generally to generic media types as you suggest, it applies to people who give otherwise generic media types application-specific behavior, thereby violating the definition of the media type. Do you see the distinction?
 

"One of the easiest ways to see that is when a protocol calls for the use of a generic media type (like application/xml or application/json) and then requires that it be processed in a way that is special to the protocol/API."

Using what you bolded, that says to me that if you process application/json in a way that recognizes any structure beyond what is defined here: http://www.ietf.org/rfc/rfc4627.txt then you are not processing it in a RESTful manner.

Other specifications are allowed to modify media type registrations. In this case, this is done by JSON Schema. This isn't a novel concept, it happens out of necessity when new media codecs are introduced for use in existing media containers/file formats, and even the text/html media type has regularly been updated (the "level", "version", and "charset" parameters).
 

A generic media type is not only RESTful, but required

Please provide references where this is stated because my understanding is that use of generic media types for anything beyond what's define in their spec is not RESTful.

See my earlier reference to the "Uniform Interface" constraint, which itself requires "identification of resources; manipulation of resources through representations; self-descriptive messages; and, hypermedia as the engine of application state."

In particular, note the hypermedia constraint (a user agent must be able to read hyperlinks), and the self-descriptive constraint (no out-of-bound knowledge required to use the API, once the client has been introduced to the, it should be able to be used by following hyperlinks).

Again, if your application requires some specialized knowledge of the server in order to operate, it cannot be RESTful, violating the uniform interface constraint.
 
What makes usage of a generic media type in an API not RESTful is when you require that the media type is handled in some way special to the API. This is comparable to visiting a website, and it tells you "Your web browser must treat the <pre youtube-src="..."> tag with our special provided plugin in order to play videos". This is "processed in some way special to the API", and this is not RESTful. A media type must act consistently no matter what API it is being used with.

Reviewing this I agree.  But reading (most of) what else you've written I can't help but think that your understanding of "special to the API" is very different from my understanding of that same phrase.  To me "special to the API" means the API is using the media type in a manner that is not defined in the media type specification. Period.  

What am I proposing that is "not defined in the media type specification"? A generic user agent does not need to understand the "profile" parameter in order to use a server that serves it. This is vastly different than a server which uses a newly invented media type: A generic user-agent will not be able to understand this.
 

For example, in HTML there is an <a> tag and an <img> tag; the former has @href and the latter @src but while both accept URL values the browser processes those URLs differently and the browser has in-build knowledge of <a @href> vs. <img @src>.

Similar if you received a representation in the generic media type application/json like below and your client was programmed to navigate to the "href" in the "a" link then it would be doing something "special to the API" and would thus be non-restful because the JSON does not define the meaning of "a" nor "href" and especially not what the value of "cart" means for "rel": 

  "a": {
      "rel": "cart",
      "href": "http"//api.example.com/cart"
   }
}

The browsers in-built knowledge of <a> and <img> is defined by the text/html or application/xhtml+xml media types. Likewise, if you used the example above and created a media type called e.g. application/hyperlinked+json, and which could be used by any API and implemented by any user-agent, then that would also be RESTful. Sending this document as application/json, however, would not be RESTful, it would be like sending what is otherwise HTML as text/plain. In order to understand that there are hyperlinks in that document when served as application/json, the user-agent would have to be told out-of-bounds to modify its behavior (or we'd have to update the JSON RFC to add this behavior, doubtful for obvious reasons, but could be possible for other media types).

The thing he is talking about is requiring specialized knowledge in order to interface with an API. A generic user agent like my web browser should be able to pull up a website and just use it, never having seen it before.

We are talking about media types for use with APIs; why keep bringing up browsers loading websites?

REST isn't a dissertation about APIs. (Go find me one time it ever talks about APIs!) Rather, it's about networked application architectures, and as such, an HTML website is the quintessential RESTful API. It uses URIs, it has a uniform interface, it has hypertext, server functionality evolves independently of client functionality. If we don't use websites for our APIs, it's because robots require highly predictable responses from the server, more like an RPC. In HTML, this could be done with "id" attributes, or more frequently, a JSON response along with an implicit understanding that reverse compatibility won't be broken in the future.
 

If you want to add special, optional behavior to your API, then fine, but that's RPC behavior on top of the RESTful part of your API.

How do you make the leap from optional behavior to "then it must be RPC?"

Optional behavior would be an RPC-like behavior, which is distinct from REST behavior (but not mutually incompatible).
 

A schema is provided as a link, any generic client can follow that link, and any generic client can understand JSON Schema, and imbue the received JSON with meaning. What he is describing here is introducing application-specific behavior, like the "youtube:player" tag that I talked about.

My understanding is that creating discoverable interfaces is not what Roy intended for REST; to whit (emphasis mine):

Roy: The interface doesn’t need to be discovered. It is defined right there in the hypertext. The representation tells the client how to compose all transitions to the next application state. This could be as simple as an anchor or as complex as a java applet.

The REST API I am proposing is not typed, to a REST client, it is application/json (strictly, this still isn't RESTful as JSON lacks hypertext.

Correct, it's not RESTful. 

Um, okay? What of it?
 

If the client were provided a Link header to the JSON Hyper-schema, it would become more RESTful.).

It's not RESTful according to my interpretation of Roy's statement: 

"The interface doesn’t need to be discovered. It is defined right there in the hypertext."

I didn't say it perfectly satisfies the constraint, but it comes closer than anything else that's been suggested: Your suggestion for an application-specific media type has no hypertext whatsoever. Please make it clear how you you would improve on my suggestion before deciding to critique it.

Nonetheless, I don't believe this is the case. HTML necessarily requires following hyperlinks at viewing-time in order to be used, including XSLT, ECMAScript/Javascript, frames, and informative technologies like CSS and images. Why can't the same be true for JSON? JSON Hyper-schema sounds significantly less complex than "as complex as a Java applet" (something which also has to be downloaded). So I don't believe this is "discovery". However if "being defined right there in the hypertext" means you can't even be required to follow a hyperlink, then all JSON formats will fall on their face, including what I believe is your proposal.

Mike Schinkel

unread,
Jun 22, 2013, 1:58:41 PM6/22/13
to api-...@googlegroups.com
On Jun 22, 2013, at 8:26 AM, Austin Wright <diamon...@users.sourceforge.net> wrote:
...

This discussion between you and me has become circular. I've already addressed each of your points at least once except for the strawman arguments you attributed to me that I did not make.

Since we are the only two debating on this branch of this thread it appears no one else cares to be drawn into a circular argument and thus our debate have little overall value. Rather than waste several more hours continuing this debate I will bow out at this time.

-Mike 

Austin Wright

unread,
Jun 22, 2013, 6:07:51 PM6/22/13
to api-...@googlegroups.com
On Saturday, June 22, 2013 1:22:33 AM UTC-7, Mike Kelly wrote:

So... What are the actual, practical differences in evolvability between a versioning technique using profiles than one using custom media type identifiers?

Well since the distinction is over usage of media types, one implication would be in Content-Type negotiation. If either a client or a server wants to indicate their support for a new feature or a breaking change, they might use the Accept header to do so. However, if you implement backward-compatible new feature, or a forward-compatible breaking change, using an entirely new media type breaks both forward and reverse compatibility.

Perhaps you want to use more advanced Content-Type negotiation as I do. A client should be able to send to my server e.g.:

Accept: application/json;profile=http://example.com/v2/post.json, application/xhtml+xml, application/json

Meaning "Send me a v2-post as JSON, or else HTML, or else any JSON you have."

Mostly this impacts the use of generic user-agents. Can your Web browser navigate the API? Requiring a custom media type breaks this. If you want to support such an API, it should also support a generic media type like text/html or application/json (along with a Content-Location header).

Austin.
Message has been deleted

Thiyagu Dakshinamurthy

unread,
Jan 28, 2016, 9:37:07 AM1/28/16
to API Craft
If you apply design thinking, the client should not be passing the version number in the request, assuming each client is recognised by app id, versioning should be associated to the app id on there server rather than having client pass the version in the request, which increases the complexity of interactions.  I employed this pattern in recent project and there has been no issues regarding versioning. On server side resources request are processed based on app id information available in the resource request. thus simplifying version management in legacy client deployed on millions of mobile apps. when new version of mobile app is launched, which wants to use newer/updated api services, it would get a new app id. its as simple and  transparent as that.

cheers

Thiyagu Dakshinamurthy

unread,
Jan 28, 2016, 9:42:46 AM1/28/16
to API Craft
following up on the post below... Versioning being a API governance function on the server side, each api (version) should support a deprecation and retirement stage, which in my pattern translates to each client app id would be deprecated and retired in stages.which made perfect sense in mobile app world.
cheers
thiyagu
Reply all
Reply to author
Forward
0 new messages