API versioning

952 views
Skip to first unread message

Indumathi

unread,
Aug 8, 2012, 3:47:19 AM8/8/12
to api-...@googlegroups.com
Is it necessary to include version if I m introducing new urls for resources in my API

Happy to hear any suggestions over this.

Thanks
Indu

gavind

unread,
Aug 8, 2012, 10:03:07 AM8/8/12
to api-...@googlegroups.com
Including a version is good API practice.

If your existing API includes a version, you would need to bump up the minor version (not the major version), if all you are doing is extending your API services.
If you are modifying existing API services, thereby potentially making your API incompatible with earlier versions, you should bump up the major version of your API. Bumping up the major version, usually indicates the non-backwards compliance.

If your API does not currently include a version, you should version it, and may unfortunately need to support both API instances. If you can get your current API clients to switch, you can happily support just the API instance with the version.

Peter Williams

unread,
Aug 8, 2012, 10:22:59 AM8/8/12
to api-...@googlegroups.com
On Wed, Aug 8, 2012 at 1:47 AM, Indumathi <indu...@gmail.com> wrote:
> Is it necessary to include version if I m introducing new urls for resources
> in my API

I strongly advise against using the URIs as a way to version an API.
The URI should identify a conceptual entity (ie, a resource). That
conceptual entity is the same whether the response to a GET request is
the first flavor of JSON document you designed for it or the second.
Mime types are the way to identity document formats on the web.
Defining a mime type for each version of the documents your API
produces and using content negotiation to allow the client to request
which flavor of response it needs to accomplish it's goals is the best
way to handle API versioning.

Peter
barelyenough.org

PS: <http://barelyenough.org/blog/tag/rest-versioning/> has more of my
opinions on this subject.

mca

unread,
Aug 8, 2012, 10:24:21 AM8/8/12
to api-...@googlegroups.com
I can't recall the last time i actually included "version" information in one of my API implementations.

For example, I implemented an API six years ago at an organization where one in three of every client app was written by someone outside the organization. This organization has "released" three new products on this API and "rev'd" two of the products at least twice in that six year span. To this day, 100% of the existing client apps still work just fine. None experienced "breakage" due to any "upgrade" and many of them actually "auto-magically" acquired new features without the need for re-coding the clients over these years.

I just don't see a need for "version" information on the public-facing interface for Web APIs.

mca


--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group, send email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft?hl=en.
 
 

Pat Cappelaere

unread,
Aug 8, 2012, 10:34:27 AM8/8/12
to api-...@googlegroups.com
Peter,

So, you would rather see a mime-type like:

application/json; profile='/resource'; describedby="schema.rnc"; version="1.1"

Pat.

Aaron Korver

unread,
Aug 8, 2012, 10:36:49 AM8/8/12
to api-...@googlegroups.com
Eww :-)

Peter Williams

unread,
Aug 8, 2012, 12:17:24 PM8/8/12
to api-...@googlegroups.com
> On Wed, Aug 8, 2012 at 9:34 AM, Pat Cappelaere <cappe...@gmail.com> wrote:
>> So, you would rather see a mime-type like:
>>
>> application/json; profile='/resource'; describedby="schema.rnc";
>> version="1.1"
>>
> On Wed, Aug 8, 2012 at 8:36 AM, Aaron Korver <aaron....@gmail.com> wrote:
> Eww :-)

Agreed.

I'd rather see something like `vnd.my-company.procurement+json`. These
days i don't put a version number in the mime type because, as mca
pointed out earlier, you really should be trying to avoid breaking
changes to your APIs. If you ever do need breaking changes you can
still create a new mime type for your new format. This approach
provides a versioning escape hatch should you need it but without the
cognitive overhead of explicit version numbers.

It also can be helpful if you are working in a space that might become
standardized. If a standard media type is ever created for your domain
you will probably want to support it. The new standardize format would
almost certainly be incompatible with your proprietary format. With a
media type and content negotiation approach it is just another
representation, rather than each version having to be a different api.
(This happens to be something i am experiencing first hand at the
moment.:) )

Peter
barelyenough.org

Jack Repenning

unread,
Aug 8, 2012, 12:44:24 PM8/8/12
to api-...@googlegroups.com
On Aug 8, 2012, at 7:24 AM, mca <m...@amundsen.com> wrote:

I just don't see a need for "version" information on the public-facing interface for Web APIs.

Versioning becomes necessary when there are incompatible changes, particularly when there's a change from "some value or relationship is optional" to "it's now required."

Suppose your application includes a user object, whose fields are standard profile things. Suppose, initially, you allow but do not require an email address. Then, one day, the Product Owner decides that the email address shall henceforth be required.

If you simply change your registration process (aka "user creation," aka "POST /users") to enforce the requirement, you instantly break existing partner aps. Better to have a transition period, during which you can monitor usage and nag your partners.

If your original design for this operation was "POST /1/users", then you can create a v.2 API, with a "POST /2/users", and let it run side by side with the /1/ API for a while. That also makes it handy to monitor usage, from log files, so you know who has, and who has not, switched to the new API version.

Jack Repenning

I was born not knowing, and have had only a little time to remedy that since then.

 -- Richard Feynman




Steve Klabnik

unread,
Aug 8, 2012, 12:45:35 PM8/8/12
to api-...@googlegroups.com
> Versioning becomes necessary

What version of Google are you currently running? When they updated
their site to add in the autocomplete functionality, did you have to
upgrade your browser?

Jack Repenning

unread,
Aug 8, 2012, 12:51:07 PM8/8/12
to api-...@googlegroups.com
On Aug 8, 2012, at 7:22 AM, Peter Williams <pe...@barelyenough.org> wrote:

> On Wed, Aug 8, 2012 at 1:47 AM, Indumathi <indu...@gmail.com> wrote:
>> Is it necessary to include version if I m introducing new urls for resources
>> in my API
>
> I strongly advise against using the URIs as a way to version an API.
> The URI should identify a conceptual entity (ie, a resource). That
> conceptual entity is the same whether the response to a GET request is
> the first flavor of JSON document you designed for it or the second.
> Mime types are the way to identity document formats on the web.

Not all "versioning" problems have to do with the format of the documents. APIs consist not only of exchanged data, but also expected behavior. If a change has to do with expectations (requiring fields that were formerly optional, changing prerequisites, or similar), then there's no way to express that as a different document type: it's not a different document type, only a different expectation about the document.


Jack Repenning




Ronnie Mitra

unread,
Aug 8, 2012, 12:56:58 PM8/8/12
to api-...@googlegroups.com
Hi Jack,

I agree with the sentiment that API versioning can be useful, but in your example:

"Suppose your application includes a user object, whose fields are standard profile things. Suppose, initially, you allow but do not require an email address. Then, one day, the Product Owner decides that the email address shall henceforth be required."

Couldn't I keep the API version-less by making the email address field optional while logging those client IDs who do not supply email addresses in requests?  I could even provide a warning in the response indicating that the field will be required in the future.  This would require additional implementation effort on the server/gateway, but would ease the burden of client apps having to send messages to a new URL.

thanks,
Ronnie 


mca

unread,
Aug 8, 2012, 1:02:10 PM8/8/12
to api-...@googlegroups.com
Jack:

Is it *possible* to change message-level interactions such that you break existing clients? you betcha!'
Is this *REQUIRED* in order to modify client-server interactions over time? nope.

My point here is this, just because you *can* create changes that break existing clients, does not mean you *must* and my experience is that you need not do it while introducing new features/requirements over time.

to follow up on Steve's POV:
What version of HTML are your running (not what version of the browser clieint, what version of the _message_)?
Have there been features added to the HTML _message_ format over the last 15 years? yes
Have these added features *broken* existing clients (i.e. browsers written years ago? no.

Finally, versioning is a *technique*, not a feature. It's purpose is to prevent problems of incompatibility between components. Over the public HTTP Web, using digits in the URI, header, or media type are not *required* in order to prevent incompatibility between clients and servers.

Peter Monks

unread,
Aug 8, 2012, 1:11:06 PM8/8/12
to api-...@googlegroups.com
Doesn't HTML benefit greatly by virtue of the fact that the ultimate consumer of the information is a human being?  Recall that HTML supports backwards compatibility by allowing the browser to simply ignore anything it doesn't understand, relying on the human's ability to deal with the fallout.

I guess I'm not clear on what HTML can teach us about designing APIs that are primarily consumed by computer systems and _not_ humans.  Perhaps you can clarify that?

Cheers,
Peter

Pat Cappelaere

unread,
Aug 8, 2012, 1:14:18 PM8/8/12
to api-...@googlegroups.com
I add to change much of my services when they change the Google Maps API.
Pat.

Jack Repenning

unread,
Aug 8, 2012, 1:14:18 PM8/8/12
to api-...@googlegroups.com
On Aug 8, 2012, at 9:56 AM, Ronnie Mitra <ronnie...@gmail.com> wrote:

Couldn't I keep the API version-less by making the email address field optional while logging those client IDs who do not supply email addresses in requests?  I could even provide a warning in the response indicating that the field will be required in the future.  This would require additional implementation effort on the server/gateway, but would ease the burden of client apps having to send messages to a new URL.

Sure, there are always multiple ways to do anything. And I'm not going to argue that my way is spectacularly better than your way (we can still be friends ;-). But it does seem to me that your way, sooner or later, brings your implementation into conflict with your documentation and contract: you wrote dox that said "'POST /user' includes an optional email address," your partners wrote code that depends on that promise, yet sooner or later you're going to start rejecting "POST /user" requests that lack email. My way, "POST /1/user" without email remains legal up until the entire /1/ API version is retired; meanwhile "POST /2/user" is documented to require email, requires email from day one, and continues to require email until the end of time (or its own retirement).

Jack Repenning

Ah, the curses of technomaniacal society.  The natural man never had to think up new IM handles!  True, he had to think of a cool design for the paint on his face and a clever way to put the handprints on his horse's behind.  But I'm pretty sure I have more logins and handles and screen names and email addresses and aliases than most villages of natural men had horses.  I even have a passworded vault on my smart phone that holds my passwords for other vaults.  I doubt many natural men had horses to keep track of their horses....

"Hey, Tinkers-With-Scripts, chief Fudges-On-Deadlines has new PDA.  Him heap big uber-geek."




Steve Klabnik

unread,
Aug 8, 2012, 1:14:57 PM8/8/12
to api-...@googlegroups.com
> I add to change much of my services when they change the Google Maps API.

I didn't say Google maps, I mean when you direct your API client at
www.google.com.

Jack Repenning

unread,
Aug 8, 2012, 1:16:03 PM8/8/12
to api-...@googlegroups.com
On Aug 8, 2012, at 10:02 AM, mca <m...@amundsen.com> wrote:

Is it *possible* to change message-level interactions such that you break existing clients? you betcha!'
Is this *REQUIRED* in order to modify client-server interactions over time? nope.

You, apparently, work with more flexible (or sensible) Product Owners than I.

Jack Repenning

A young man wrote to Mozart and said:

Q: "Herr Mozart, I am thinking of writing symphonies. Can you give me any suggestions as to how to get started."
A: "A symphony is a very complex musical form, perhaps you should begin with some simple lieder and work your way up to a symphony."
Q: "But Herr Mozart, you were writing symphonies when you were 8 years old."
A: "But I never asked anybody how."


Pat Cappelaere

unread,
Aug 8, 2012, 1:23:52 PM8/8/12
to api-...@googlegroups.com
Sorry, I believed that the discussion was centered around M2M API's
Pat.

Jack Repenning

unread,
Aug 8, 2012, 1:28:02 PM8/8/12
to api-...@googlegroups.com
On Aug 8, 2012, at 9:45 AM, Steve Klabnik <st...@steveklabnik.com> wrote:

>> Versioning becomes necessary[when there are incompatible changes]
>
> What version of Google are you currently running? When they updated
> their site to add in the autocomplete functionality, did you have to
> upgrade your browser?

That wasn't an incompatible change, a key distinction I've restored to your quote.

Now, if Google were to change things so that you *must* specify "AND" or "OR" between each search term, so that familiar queries like

horse dancing olympics

became simply illegal, and had to be expressed as

horse AND dancing AND olympics

then *that* would be "incompatible."

As noted elsewhere in the thread, Google would probably still not clutter their URL with version info for this (assuming they did such a ghastly thing!), they'd just report some sort of error and allow the infinitely adaptable human component to learn and compensate. But when we're programming to an API, we rarely include a massive neural network in the app: we rely on the API to include enough consistency and contract to save us that overhead.

The autocomplete example also highlights another distinction we should be making in this discussion. In the autocomplete case, the code on both sides (browser and servers) comes from the same authors (Google), and can be trusted to be of matching version (JavaScript being downloaded at run-time). Under these assumptions, explicit versioning may not ever be needed, you just change both ends simultaneously. But when you're building an API for others to use, when your partners will be embedding their API-using code in apps installed on the client machine, or even JavaScript-downnloaded from partner servers rather than your servers, then your life may become more difficult, and you may need explicit control of versioning.

Jack Repenning

186,262 miles per second -- Not just a good idea ... it's the LAW!!!




Steve Klabnik

unread,
Aug 8, 2012, 1:32:27 PM8/8/12
to api-...@googlegroups.com
Machines can absolutely search Google:

query = "steve"
base_uri="https://www.google.com/search"

data = fetch_html(base_uri)

action = search_xpath(data, "//form")
param = search_xpath(data, "//form/input['type'='text']")['name'] # or
whatever, my xpath is fuzzy and I'm proving a point

data = fetch_html("#{base_uri}/#{action}?#{param}=#{query}")

Obviously this is super rough, but you get the idea.

mca

unread,
Aug 8, 2012, 1:48:50 PM8/8/12
to api-...@googlegroups.com
<snip>

I guess I'm not clear on what HTML can teach us about designing APIs that are primarily consumed by computer systems and _not_ humans.  Perhaps you can clarify that?
</snip>

good Q!

here's what I learned when inspecting HTML and other hypermedia types[1] and how I applied them to designing APIs to be consumed by developers to write apps that are "driven" either by humans or by 'bots. Note I mention developers here. devs are the first-level consumers of APIs; even devs that write HTML clients<g>.

there is a class of types that contain not just formats and data markup rules, but also interaction rules. These are defined as part of the message type itself; most commonly called links and forms. HTML, Atom, SVG, VoiceXML, etc. all contain these native interaction elements; often called affordances. I did some basic research on this a few years ago and, as a start, identified a common set of these features and named them "Hypermedia Factors" or H-Factors[2].

These factors can be applied to any format/message model. XXX did this with Atom[3] MIke Kelly does this w/ HAL[3]. I've done it w/ Collection+JSON[4]. Others are doing similar work. YOu'll note that all these designs focus on the affordances and reduce focus on an actual application instance (blogs, accounting, etc.). Atom uses @rel to communicate important information about the interactions between client and server, so do HAL and CJ. HAL & CJ, like HTML, support adding application-specific information via @name/@id/@class/@rel (each in their won way) attributes and tying them to a shared vocabulary.

HTML relies on humans to understand the problem domain using visual and text cues. HAL, Atom, CJ and others rely in machines to understand the problem domain using text cues, too.  This is how HTML can inform message designs that work for M2M APIs. when building apps for these media types, devs "code-in" understanding of teh affordances and "add-on" understanding of the domain specifics. This results in a kind of "generic" (at varying levels) explorer tooling similar to HTML Browsers. HAL Talk[6] is a good example. There is also at least one for CJ[7].

I've built a handful of machine apps that use these media types to do 'bot work (collect data, parse, update, write back to servers, etc.) and more than one "generic" browser that automatically understands the new search/sort/filter options for collections of data; even on servers that are implemented by others.

FWIW, I spent a great deal of time on this an you'll find more of my POV online and at O'Reilly's web site (plug!).

Cheers.

[1] http://www.amundsen.com/hypermedia/
[2] http://amundsen.com/hypermedia/hfactor/
[3] http://tools.ietf.org/html/rfc5023
[4] http://stateless.co/hal_specification.html
[5] http://amundsen.com/media-types/collection/
[6] haltalk.herokuapp.com/explorer/hal_browser.html
[7]
http://collection-json-explorer.herokuapp.com/render?url=http%3A%2F%2Femployee.herokuapp.com%2Femployee#template

Jack Repenning

unread,
Aug 8, 2012, 2:06:48 PM8/8/12
to api-...@googlegroups.com
On Aug 8, 2012, at 10:48 AM, mca <m...@amundsen.com> wrote:

there is a class of types that contain not just formats and data markup rules, but also interaction rules. These are defined as part of the message type itself; most commonly called links and forms. HTML, Atom, SVG, VoiceXML, etc. all contain these native interaction elements; often called affordances. I did some basic research on this a few years ago and, as a start, identified a common set of these features and named them "Hypermedia Factors" or H-Factors[2]. 

HTML provides affordances for some classes of expectations, but handles other kinds in other ways.

To take a familiar example, HTML pages that accept credit card information "expect" it to be entered without spaces (universally, so far as I'm aware). This wildly counter-intuitive expectation is always backed by one of the world's most commonly used error messages "Please enter credit card number without spaces." Humans are remarkably effective at figuring out what to do next at this point. Even the first time they encounter this. Even while grumbling "we put a man on the moon, you can take out the dang spaces".

Since we're talking about "versioning": if some web site were originally created to accept credit card numbers with the spaces, just like they're embossed in the card, and then later changed to follow "Generally Accepted Annoyance Practices" by refusing the spaces, well then the humans would, however gracelessly, comply. But it's hard to imagine an API client, not specifically challenged with this unexpected change, adapting at all, with or without grace. Humans are an amazingly powerful component, and free besides, and HTML interfaces abuse the privilege extravagantly. APIs have less scope for that.

Jack Repenning

When managers hold endless meetings, the programmers write games.
When accountants talk of quarterly profits, the development budget is about
to be cut.  When senior scientists talk blue sky, the clouds are about to
roll in.
Truly, this is not the Tao of Programming.
When managers make commitments, game programs are ignored.  When
accountants make long-range plans, harmony and order are about to be restored.
When senior scientists address the problems at hand, the problems will soon
be solved.
Truly, this is the Tao of Programming.
-- Geoffrey James, "The Tao of Programming"




Greg Brail

unread,
Aug 8, 2012, 2:06:58 PM8/8/12
to api-...@googlegroups.com
I think that putting a version on your API is a good idea. Lots of APIs use the URI path in order to do this by prepending a "1" or a "v1". Lots of developers understand it and find it easy to use, and I think it's a pattern that has been proven to work.

I also feel strongly that this version needs to be a single number, and it refers to the version of the interface defined by your API -- not the implementation. Plus, you only need to change it when you have changed the interface in an incompatible way. That means no minor revisions, no dates, etc.

In other words, when the client makes an API call to "http://api.foo.com/v1/bars/baz", then it is telling the server that it is looking for version 1 of the contract. If the server decides that /bars/baz is now a 404, then the server has changed the contract in an incompatible way.

So, did you stick a "1" or a "v1" in your URI path or host name for your API? Great.

Now, did you just add a new URI path? You don't need to change it -- you didn't change the API in an incompatible way.

A lot of API providers and API users find that this basic pattern works for them.

Now, what if you decide down the road that you want to do everything using Collection+Json or something similar -- well then you have introduced version 2.

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group, send email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft?hl=en.
 
 



--
Gregory Brail  |  Technology  |  Apigee

mca

unread,
Aug 8, 2012, 2:14:10 PM8/8/12
to api-...@googlegroups.com
<snip>
To take a familiar example, HTML pages that accept credit card information "expect" it to be entered without spaces (universally, so far as I'm aware). This wildly counter-intuitive expectation is always backed by one of the world's most commonly used error messages "Please enter credit card number without spaces." Humans are remarkably effective at figuring out what to do next at this point. Even the first time they encounter this. Even while grumbling "we put a man on the moon, you can take out the dang spaces".
</snip>

HTML has no such expectation. the *implementation* on the serer that *uses* HTML may have this expectation. To prove the point, the same server may have the expectation regardless of the media type used to represent the message (HAL, CJ, Atom, etc.).

Jack Repenning

unread,
Aug 8, 2012, 2:35:14 PM8/8/12
to api-...@googlegroups.com
On Aug 8, 2012, at 11:14 AM, mca <m...@amundsen.com> wrote:

HTML has no such expectation. the *implementation* on the serer that *uses* HTML may have this expectation. To prove the point, the same server may have the expectation regardless of the media type used to represent the message (HAL, CJ, Atom, etc.).

That's certainly true, I was using "HTML" to mean something rather vague, like "the HTML world." HTML proper is a medium in which developers create applications (web sites), and it is the applications that may have these expectations. So, also, an API may be implemented in some media, like URLs and HTTP headers and JSON and XML, but API designers are creating applications  (and meta-applications, the opportunity for additional applications), and "expectations" are in the (meta-)application, not the medium.

But I guess I've lost your original point. If you're learning lessons from the medium of HTML, they may well benefit the medium of the API (URLs and headers and JSON and XML). But I didn't think anyone was proposing to version those, only to carry therein the version information for the API crafted in that medium. Was I wrong to understand you to be applying HTML medium design lessons, to the API application design process?

mca

unread,
Aug 8, 2012, 2:36:46 PM8/8/12
to api-...@googlegroups.com
<snip>
Was I wrong to understand you to be applying HTML medium design
lessons, to the API application design process?
</snip>
nope.

Mike Kelly

unread,
Aug 9, 2012, 4:59:39 AM8/9/12
to api-...@googlegroups.com
Exposing any of your application via URI patterns should be avoided
wherever possible.

Assuming you buy into the hypermedia thing, then you can version your
individual link relations. This is preferable to both versioning in
the media type identifier and versioning in the URI.. the former
because link rels are far more granular (and discoverable) than media
type identifiers, and the latter because versioning via the URI is
brittle.

To be clear, a new version of a link relation means that there was a
breaking change (an additional required field, change to workflow,
etc). Non-breaking changes do not require a new link relation, they
require an update to the link relation's documentation - this change
should be transparent to any existing clients.

I don't think it needs to much more complicated affair than this when
we are talking about APIs. Drawing parallels between human-consumed
HTML web apps and machine-consumed APIs is not a good idea, either -
so don't waste too much time thinking about that.

Cheers,
M

On Wed, Aug 8, 2012 at 8:47 AM, Indumathi <indu...@gmail.com> wrote:
> Is it necessary to include version if I m introducing new urls for resources
> in my API
>
> Happy to hear any suggestions over this.
>
> Thanks
> Indu
>
> --
> You received this message because you are subscribed to the Google Groups
> "API Craft" group.
> To unsubscribe from this group, send email to
> api-craft+...@googlegroups.com.
> Visit this group at http://groups.google.com/group/api-craft?hl=en.
>
>



--
Mike

http://twitter.com/mikekelly85
http://github.com/mikekelly
http://linkedin.com/in/mikekelly123

Pat Cappelaere

unread,
Aug 9, 2012, 7:49:26 AM8/9/12
to api-...@googlegroups.com
Mike,

Ok… let's assume that we buy into the Hypermedia thing…
I have created a task resource and want to start it.
I need two parameters to POST.
I changed the API from requiring integers to floats and the first parameter is limited from -90.0 to +90.0 and the second parameter -180.0 to +180.0.

I hear you that I can change the link action for that task resource.
How do I convey to my client that the API has changed fairly drastically and my parameters are typed differently and now have a range?
Thanks,
Pat.

chris...@gmail.com

unread,
Aug 9, 2012, 8:13:21 AM8/9/12
to api-...@googlegroups.com
On Thu, 9 Aug 2012, Mike Kelly wrote:

> I don't think it needs to much more complicated affair than this when
> we are talking about APIs. Drawing parallels between human-consumed
> HTML web apps and machine-consumed APIs is not a good idea, either -
> so don't waste too much time thinking about that.

This sounds like bait, but I'll bite anyway, because I like to
participate in such things. Take this with a bit of I don't live in
the real world salt.

Making a distinction between "machine-consumed APIs" and, well,
everything else seems limiting.

The win from having resources on the (a?) web, using common and
visible media types, and using scrutable URIs is that all sorts of
things, be they machines or humans, can interact with those resources
and do all sorts of stuff.

I'm being a hippy here, but that is, at core, a political statement
about participation and control.

It's no surprise that organizations pigeonholed as enterprisey want to
limit participation and maximize control. In that context, having a
scrutable API means that some yahoo can come along and subvert the
imposed information controls.

Except in extremely rare cases, this is a good thing.

Thinking that has led me to a few conclusions about API designs:

* publish your resource URIs and limit (if not outright remove)
dependencies between resources
* don't require hypermedia (which is essentially the above sentiment
repeated)
* Use generic media types (text/plain, text/html, application/json)
and let the client decide how it chooses to interpret them

and to bring this back to the thread topic:

* Don't worry about versioning. If you've got the above sorted, you
probably won't need it, and if you find that you do, then perhaps
what you have is another resource, not a different API.

A profusion of custom media types and a need for versioning is a
hallmark of perhaps thinking a bit too much like RPC or SOAP or
something. That level of complexity is certainly available to you with
a strong REST-over-HTTP API, but is it worth the effort?

If you find that your problem area requires strong and detailed types,
is going to be impacted by slight changes in stucture (thus requiring
versioning) and is encumbered with complexity from trying to manage a
lot of state, it might be worth considering something other than HTTP.

Use HTTP to expose things. With flexibility.

--
Chris Dent http://burningchrome.com/
[...]

Pat Cappelaere

unread,
Aug 9, 2012, 8:47:17 AM8/9/12
to api-...@googlegroups.com

On Aug 9, 2012, at 8:13 AM, chris...@gmail.com wrote:

>
> If you find that your problem area requires strong and detailed types,
> is going to be impacted by slight changes in stucture (thus requiring
> versioning) and is encumbered with complexity from trying to manage a
> lot of state, it might be worth considering something other than HTTP.

This really hurts my feeling, Chris. :)
A good API has to address this issue to be widely accepted (and battle hardened).
My problem does require strong and detailed types. It needs to evolve over time.
I am not going to go back to the SOA route. I see no reason for that and that would kill me.
Versioning is not necessary for all apps but is a must for some. We just need a clean way to do it.
There is nothing wrong with HTTP nor REST. Lets not make that a battle ground.

Pat.







Daniel Roop

unread,
Aug 9, 2012, 8:52:47 AM8/9/12
to api-...@googlegroups.com
Since this distinction has been pointed out int he past, I will make it here.  Not all APIs need be "REST" based.  And by REST I mean Hypermedia Driven aka RMM Level 3.   I think if you choose not to go the Hypermedia route (which I wouldn't) then versioning in the URL as described by Greg Brail above is completely workable solution.

Once you drink the Hypermedia Kool-aid it breaks down.  Imagine I have three services, let's call them Catalog, Reservation and Itinerary.  Let's aslo assume that Reservation and Itinerary "link" to catalog information.  If you are providing the version in the URI (ala /v1) You are putting the burden on the client to understand more than one version of the Catalog data you are linking to, if Reservation and Itinerary do not agree on which version you should be linking to.  But this isn't fair, the client is the only one that knows what data he needs from the catalog at the other end of that link, and should ask for the one he wants.  SO my perspective is URL based "version" paths break down when you start linking because
- Puts more burden on the client to understand N number of versions of the same content
- THe alternative is providing which version you care about to all other services which seems slightly unwieldy.

The recommendation I have landed on is that in a Hypermedia Based design I agree with what Mike and mca have been saying (suprise suprise the REST zealots agree ;-)).  I talk about two ways to version a hypermeida API

:Representation Versioning:
This is when the format of your data has changed, but the concept has not.  Imagine I have a /person/{personId} resource.  The person is still a person is still a person.  He has a name.  Maybe it is represented like this
{
    "firstName" : "John",
    "lastName" : "Doe",
    "address" : {
         ...
    }
}

I want want to restructure that, to the following
{
    "name" : {
        "first" : "John",
        "last" : "Doe"
    }
    "address" : {
         ...
    }
}

It would be a backwards incompatible change, and therefore I need to version.  I would do this through the Content-Type.  The easiest way to do this is through adding a version Accept param to your content type. So the original could be application/vnd.apicraft;type=Person;version=1 and the second application/vnd.apicraft;type=Person;version=2. You would typically take advantage of this if you want to change the way some data is represented.  It is easier to imagine this between two completly different formats.  Imagine I have a reservation /reservation/1234, in a hypermedia/rest world I would use content-type negotiation to get the json document, version the xml document vs the pdf.  Same concept.  Typically on the web you see these represented as different links, I actually think this is one of the cases where the human component hurts us.  They have no easy way to say what representation they want simply by clicking a link, so we create different links (and urls) for different content types.  But it isn't required in the m2m world, since the machine can specify which representation it wants.

:Resource Versioning:
This one is where the concept has change.  So building on the previous example let's say, I wanted to have a smaller resource that only dealt with the name, not the address.  This too would be a backwards incompatible change so I need to "version" this somehow.  Since this is a resource model change, I would use the ID for the resource (aka the URL).  But I tend to shy away from "numbers" in this case, because I subscribe to the theory that if you can't name it you don't understand it.  Since you have created a new concept you need to come up with a meaningful name for that concept.  In this case I would call it /person-name/{personId}.  That would just return the name structure, and could even use the same Content-Type as above, but the resource is different and the links to it are probably different.


Some other thoughts:
- I agree with mca that you do not need to make backwards incompatible changes, but I accept this is the tendency for most developers (on both ends) so this is a hard problem to overcome (although not impossible).
- To you original question...IN any of the solutions I have described (or any other's on this thread) I think the answer to your question is no, you don't need to rev the API version.
- We have instituted a rule that (in any of the solutions) that if the "version" is not specified (whether it is /v1/.. or in the content-type) we assume the lowest supported version.  This has the nice side effect of letting you avoid the problem until you need to solve for it (and maybe you won't ever need too).  Google used this in their Google Data API specification as well.
- I do believe that you can draw a lot of information out of how existing Hypermedia Solutions have been implemented, including primarily presentation based ones (like HTML), but I do think M2M creates some unique challenges that HTML does have and vice versa.
- I am starting to wonder if there should be a distinction between a "bot" client and a "remote control" client.  The difference being one is a "crawler link automated program" while the other one has an eventual human on the other side.  I think there is a lot of similarity but I think the "remote control" style has the opportunity to have more "open ended" capabilities since he has a neural network on the other side.

-Daniel

P.S. I love it when this group gets a topic like this...

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group, send email to api-craft+unsubscribe@googlegroups.com.

Daniel Roop

unread,
Aug 9, 2012, 8:56:30 AM8/9/12
to api-...@googlegroups.com
Pat,

While I agree there is nothing wrong with REST, and that some APIs need versions and some don't.  I do think it is helpful to distinction between a Hypermedia API (aka REST RMM Level 3 aka the REST Zealots) an what some in this community refer to as APIs in the generic sense.  I think Hypermedia adds an interesting perspective that not all people need or should take advantage of. 

This may be colored by the fact that I think some solutions work well in a non-hypermedia api and some solutions work better (or are necessary) in a hypermedia api.  The question is which one are you implementing.  Once you know that, you will be able to answer the question better.

Mike Kelly

unread,
Aug 9, 2012, 8:57:11 AM8/9/12
to api-...@googlegroups.com
On Thu, Aug 9, 2012 at 1:13 PM, <chris...@gmail.com> wrote:
> On Thu, 9 Aug 2012, Mike Kelly wrote:
>
>> I don't think it needs to much more complicated affair than this when
>> we are talking about APIs. Drawing parallels between human-consumed
>> HTML web apps and machine-consumed APIs is not a good idea, either -
>> so don't waste too much time thinking about that.
>
>
> This sounds like bait, but I'll bite anyway, because I like to
> participate in such things. Take this with a bit of I don't live in
> the real world salt.
>
> Making a distinction between "machine-consumed APIs" and, well,
> everything else seems limiting.
>
> The win from having resources on the (a?) web, using common and
> visible media types, and using scrutable URIs is that all sorts of
> things, be they machines or humans, can interact with those resources
> and do all sorts of stuff.

That's all ok, but not clear why this means it's useful to think about
evolving your API the same way you would your web application.

The clients of an API are automatons, the clients of a web app are
human. Humans and machines are fundamentally different in the way that
they consume/traverse/progress-through an app and consequently very
different in how they deal with change. Dealing with that difference
is the real challenge of building evolvable APIs, drawing parallels is
not going to help with this.

Cheers,
M

chris...@gmail.com

unread,
Aug 9, 2012, 9:03:35 AM8/9/12
to api-...@googlegroups.com
On Thu, 9 Aug 2012, Pat Cappelaere wrote:

>> If you find that your problem area requires strong and detailed types,
>> is going to be impacted by slight changes in stucture (thus requiring
>> versioning) and is encumbered with complexity from trying to manage a
>> lot of state, it might be worth considering something other than HTTP.
>
> This really hurts my feeling, Chris. :)

Ooops, sorry about that. I was mostly goading (cheerfully I hope)
Mike.

I'm not trying to suggest that there is anything wrong with HTTP or
REST. And I'm certainly pragmatic enough to know that versioning etc
may be needed. My point was more to suggest that if after evaluating
your requirements there's still a great deal of complexity that is
hard to resolve, it might be worth looking into something considerably
more custom than HTTP.

My hope is that during the process of evaluation, much of the
complexity can be dispensed with, tossed away by changing the
constraints, sometimes even the use cases. Perhaps by offloading the
complexity to other points of focus.

> Versioning is not necessary for all apps but is a must for some. We
> just need a clean way to do it. There is nothing wrong with HTTP nor
> REST. Lets not make that a battle ground.

I'm a 100% fan of HTTP and have been accused of being a purist by
people who don't know REST and a heretic by people who do, so I guess
that makes me something like a 75% fan of REST. I'm not after a battle
ground, I'm earnest and good intentioned disagreement.

chris...@gmail.com

unread,
Aug 9, 2012, 9:22:33 AM8/9/12
to api-...@googlegroups.com
Humans write the code that drives the automatons, using their
understanding of the APIs. That understanding is enhanced by the
degree to which the API is scrutable.

So, essentially, our disagreement (if there actually is a real one,
there probably isn't much of one) is over the potential and usefulness
of evolvable automatons that consume evolvable APIs.

If you accept that there is both high potential and high usefulness
then most of what Daniel Roop has to say about versioning of
representations in hypermedia APIs seems spot on to me and I would
point the people who want actual practical answers to it.

In the ideal hypermedia API, one resource is being exposed (as the
entrypoint) so no need to version that, the rest (*snork*) of the
resources are being discovered through hypermedia so no versions there,
so that leaves the representations.

I accept that there is high potential for evolvable stuff and that it
will be very useful for a significant subset of use cases. Those tools
will be awesome.

However, if that style becomes the standard for most or all use cases,
I shall be sad because those tools, while awesome, will be hard(er) for me
to mess about with with curl.

So: I think that it is not only important but also useful to consider how
a human will traverse an API, even if it is designed for machines.

It is important because in making the API _also_ consumable by people
it can be more democratic. It is useful because designing for humans
will often mean making things less overwhelming and messy.

Pat Cappelaere

unread,
Aug 9, 2012, 9:47:25 AM8/9/12
to api-...@googlegroups.com
Please allow me to keep asking the same question… but since you have another pointed example… I will try again.
You are using for some reason the "complex" custom media type [for which I am still debating the value of :)]
so:
My automaton is dealing with APP1 that sports the custom minted: application/vnd.apicraft;type=Person;version=1

and all of a sudden, APP2 decides to upgrade to: application/vnd.apicraft;type=Person;version=2 (and not support version 1)

[and I have a few more of those to deal with…]

I am a good automaton and I follow the links very faithfully [treat them as completely opaque]
So, how do I know or infer the correct change in the API for one APP? …. 
How do I know that to task, I really need two different parameter types with two different ranges?

I do not see why custom media types help nor how Hypermedia API helps [although Siren might get pretty close… and does not need custom media types]

This is certainly a good exchange
Thanks,
Pat.


To unsubscribe from this group, send email to api-craft+...@googlegroups.com.

Kevin Swiber

unread,
Aug 9, 2012, 10:18:27 AM8/9/12
to api-...@googlegroups.com
Put simply, a breaking change to the contract requires a change to the client unless you've developed some super-smart schema-adapting components (which is possible and cool, but potentially expensive).

(Keep in mind this is a very contrived example.  Such a small detail is usually not worth a breaking change.)

Changing...

{ firstName: "Kevin", lastName: "Swiber"}

to...

{ name: { first: "Kevin", last: "Swiber" }

... is potentially a breaking change for API clients, depending on how the contract was written.

With hypermedia contracts, backwards compatibility is very important.  If you were to do this, I think a phased approach is a better way.  Some have mentioned new link relations.  That is one option.  There are more, but really... try not to break compatibility.

If you feel you really need strong versioning, I would recommend using an option that is not purely hypermedia (I believe Greg Brail had a good suggestion).  There are trade-offs, of course.  Every design has its strengths and weaknesses.  I'm putting together a matrix of this in my mind.  I need to commit it to paper.  :)

There is a lot of guidance on URI-driven approaches.  Hypermedia guidance is still evolving, but I'm expecting this to shift over the next few months.  There is room for more than one approach in this arena.  I encourage everyone to be strongly opinionated, but open minded.  I think we do a pretty good job of that on API Craft.  :)

--
Kevin Swiber
Projects: https://github.com/kevinswiber
Twitter: @kevinswiber

Pat Cappelaere

unread,
Aug 9, 2012, 10:41:09 AM8/9/12
to api-...@googlegroups.com
Kevin,

Right! This is what I am getting to.  We need room for those options.  I have not quite seen them fully written down yet (or I have been partially blind)

In the HTML hypermedia API world, you can point to a profile and update it.  Your client will know immediately that your API has changed.
In the JSON/XML world, you need to point to a schema.  Then client would know as well.  Clients could be smart or dumb but then do not blame the server if it breaks.  These are online and immediately available.  No need for out-of-band information.

If you have profiles and/or schemas, do you need custom media-types? :) here I am again….

Thanks,
Pat.

Peter Williams

unread,
Aug 9, 2012, 10:53:40 AM8/9/12
to api-...@googlegroups.com
On Thu, Aug 9, 2012 at 7:47 AM, Pat Cappelaere <cappe...@gmail.com> wrote:
> Please allow me to keep asking the same question… but since you have another
> pointed example… I will try again.
> You are using for some reason the "complex" custom media type [for which I
> am still debating the value of :)]
> so:
> My automaton is dealing with APP1 that sports the custom minted:
> application/vnd.apicraft;type=Person;version=1
>
> and all of a sudden, APP2 decides to upgrade to:
> application/vnd.apicraft;type=Person;version=2 (and not support version 1)
>
> [and I have a few more of those to deal with…]
>
> I am a good automaton and I follow the links very faithfully [treat them as
> completely opaque]
> So, how do I know or infer the correct change in the API for one APP? ….

After the change to APP2 the client will request the version=1
representation of APP2 resources and will receive "Not Acceptable"
responses that include a human readable error message. The client will
then alert a developer who will, after cursing the developer of APP2
for stupidly removing support for version=1, implement support for
version=2 representations. The updated client will thereafter make all
requests with and accept header value of "...;version=2,
...;version=1" indicating that it can deal with either. APP1 will
respond with version=1 representations and APP2 will respond with
version=2 representations.

Peter
barelyenough.org

PS: BTW, those mime types with the version and type parameters are
quite awkward and are going to be a real pain in practice. But how to
best to define media types is a different discussion...

Pat Cappelaere

unread,
Aug 9, 2012, 10:54:49 AM8/9/12
to api-...@googlegroups.com
Peter,

This is the real discussion I want to have.
This is not acceptable, IMHO.
Pat.

Peter Williams

unread,
Aug 9, 2012, 11:39:06 AM8/9/12
to api-...@googlegroups.com
On Thu, Aug 9, 2012 at 8:54 AM, Pat Cappelaere <cappe...@gmail.com> wrote:
> Peter,
>
> This is the real discussion I want to have.
> This is not acceptable, IMHO.

Why not?

Do you see an alternative? If so how it is better?

Peter

Pat Cappelaere

unread,
Aug 9, 2012, 1:11:09 PM8/9/12
to api-...@googlegroups.com

On Aug 9, 2012, at 11:39 AM, Peter Williams <pe...@barelyenough.org> wrote:

> On Thu, Aug 9, 2012 at 8:54 AM, Pat Cappelaere <cappe...@gmail.com> wrote:
>> Peter,
>>
>> This is the real discussion I want to have.
>> This is not acceptable, IMHO.
>
> Why not?
>
> Do you see an alternative? If so how it is better?

I am not an expert but I am not convinced that minting new media types help us that much.
What we are really talking about custom context (and not a different type or language).
in HTML, you would use a profile and JSON/XML a schema.
If you make that metadata available with your data as a link or other, the client knows what your context.
It will also know if it changes. It may or may not be able to adapt but it is not a server issue at that time.
At least, the client is not caught by surprise and can access all info online as needed.
So far, no custom type has been used as I can tell.

Pat.

Greg Brail

unread,
Aug 9, 2012, 1:49:21 PM8/9/12
to api-...@googlegroups.com
The thing I keep struggling with regarding hypermedia is this:

In a URI-based API (which is what I primarily work with) then the "contract" is the set of URIs and the corresponding resource definitions. So if I add a URI I have not made a breaking change to the contract but if I rename one or change the resource representation in an incompatible way (like you showed) then I have. I change the "major version number" in the URI only when I make a breaking change to the contract.

In a hypermedia-based API, then the "contract" is the set of resource representations, but also the set of link relations on each. I understand that a hypermedia-based API lets the server change the URIs if the client is carefully written to always follow them.

But what happens in a hypermedia API when a link relation is changed in an incompatible way -- it is removed, or renamed, or the resource representation is made incompatible? Isn't that also a breaking change to the contract?
Gregory Brail  |  Technology  |  Apigee

Mike Kelly

unread,
Aug 9, 2012, 2:34:03 PM8/9/12
to api-...@googlegroups.com
On Thu, Aug 9, 2012 at 6:49 PM, Greg Brail <gr...@apigee.com> wrote:
> The thing I keep struggling with regarding hypermedia is this:
>
> In a URI-based API (which is what I primarily work with) then the "contract"
> is the set of URIs and the corresponding resource definitions. So if I add a
> URI I have not made a breaking change to the contract but if I rename one or
> change the resource representation in an incompatible way (like you showed)
> then I have. I change the "major version number" in the URI only when I make
> a breaking change to the contract.
>
> In a hypermedia-based API, then the "contract" is the set of resource
> representations, but also the set of link relations on each. I understand
> that a hypermedia-based API lets the server change the URIs if the client is
> carefully written to always follow them.
>
> But what happens in a hypermedia API when a link relation is changed in an
> incompatible way -- it is removed, or renamed, or the resource
> representation is made incompatible?

A new link relation superseding it is introduced. How long (if at all)
this new relation should then run in parallel to the old is dependent
on the API and link relation in question.

> Isn't that also a breaking change to
> the contract?

Yes, automatons can't react to a breaking change like a human would -
the contract will break when the old link relation is deprecated and
removed. The important point is that the contract was exposed as and
managed via hypertext so the breaks can be managed on a granular
per-transition basis.

Cheers,
M

Mike Kelly

unread,
Aug 9, 2012, 2:36:45 PM8/9/12
to api-...@googlegroups.com
Note that versioning via the media type identifier is not granular,
not discoverable, not distributed in the same way. Versioning should
be done in a hypermedia API using link relations.

Cheers,
M

Mike Kelly

unread,
Aug 9, 2012, 3:18:27 PM8/9/12
to api-...@googlegroups.com
On Thu, Aug 9, 2012 at 12:49 PM, Pat Cappelaere <cappe...@gmail.com> wrote:
> Mike,
>
> Ok… let's assume that we buy into the Hypermedia thing…
> I have created a task resource and want to start it.
> I need two parameters to POST.
> I changed the API from requiring integers to floats and the first parameter is limited from -90.0 to +90.0 and the second parameter -180.0 to +180.0.
>
> I hear you that I can change the link action for that task resource.
> How do I convey to my client that the API has changed fairly drastically and my parameters are typed differently and now have a range?
> Thanks,
> Pat.

Neither of those necessarily require you to convey anything to your
clients (i.e. you don't need a new link relation) since you can deal
with them on the server side. Use type-coercion on the server side to
convert old integer inputs to floats, and return a 4xx if the older
clients submit a parameter that's out of range.

It doesn't really make sense to look at the latter as a need to create
a new link relation. Replacing the link relation will prevent the need
for a redundant request and 4xx response, but it will also prevent a
bunch of calls from the old client that could well be valid.. it
depends how important it is to support those potentially correct calls
from old clients vs. the cost of handling redundant erroneous requests
and having to serve out a load of 4xx responses.

Hopefully that made sense

Cheers,
M

Pat Cappelaere

unread,
Aug 9, 2012, 4:21:43 PM8/9/12
to api-...@googlegroups.com
Nice escape but that was an example :)
So you have a new possible POST action with two new parameters that I picked for simplicity (but they are slightly more complex than simple types). Lets say that they even never existed before.

Pat.

Mike Kelly

unread,
Aug 9, 2012, 4:54:41 PM8/9/12
to api-...@googlegroups.com
Right, that sounds like a breaking change so you need a new relation

Peter Williams

unread,
Aug 9, 2012, 5:04:45 PM8/9/12
to api-...@googlegroups.com
On Thu, Aug 9, 2012 at 11:11 AM, Pat Cappelaere <cappe...@gmail.com>
> I am not an expert but I am not convinced that minting new
> media types help us that much.
> What we are really talking about custom context (and not a
> different type or language).

Really? (Using the previously mentioned very contrived example) The
difference between `{"firstname":"john", "lastname":"doe"}` and
`{"name":{"first":"john","last":"doe"}` is just a difference in
context not language?

> in HTML, you would use a profile and JSON/XML a schema.

You might but i would not. I see very little value in those. Neither
allows the client to inform the server of what it actually needs and
as a client is am going to ignore any schema declaration anyway.
Either i will find the information i need in the response and progress
toward my goal or i will not find it and fail. The declared schema has
zero impact on the outcome.

> If you make that metadata available with your data as a link or other, the client knows what your context.

But only if the client understands the representation you sent it. If
the client does not understand the language you are speaking it is, as
the saying goes, up the creek without a paddle.

> It will also know if it changes. It may or may not be able to adapt but it is not a server issue at that time.

How will it know? By requesting the resource and failing while trying
to interpret the response? Seems like pretty much the same flow as i
described except without as much opportunity for the server to ease
the evolution by supporting both flavors.

> At least, the client is not caught by surprise and can access all info online as needed.

I don't see how this approach prevents the client from being surprised
by poor choices by server developers. (Not that custom media types do
either, but that seems to be what this discussion is centering on
now.)

Peter

Cappelaere Patrice

unread,
Aug 9, 2012, 10:06:28 PM8/9/12
to api-...@googlegroups.com
Peter,

For a RESTful enterprise system, there is a need to support interoperability overtime as API changes.
In you example, the client sees the change of mime-type and stops until a human does something.
Having custom mime-types that require a human look into a pdf document is not very helpful in those situations.
This is where the value is. That declared schema has everything to do with a potential successful income (especially when the context evolves)

So a custom media type does not help in either case. However, online availability of a versioned schema or profile is critical. NO?

Pat.

Mike Kelly

unread,
Aug 10, 2012, 2:17:38 AM8/10/12
to api-...@googlegroups.com
Link relations should be URIs for this reason and its why I prefer them over media type versioning since they are more discoverable and granular.

Pat Cappelaere

unread,
Aug 10, 2012, 7:45:34 AM8/10/12
to api-...@googlegroups.com
Mike,

But not quite off the hook though…

How do you tell your client that the API has "drastically" changed?
That may be there is another kinda similar but not quite link to consider following? How is that semantic conveyed?
Wouldn't be extremely dangerous to lead that client through a new link with evolving parameters and end up crashing your server? (not that it would really happen to us)

How do you do these different actions with HAL for instance?

Are you relying on a special implementation of the client?

By the way, I am looking for examples of Hypermedia API's (not just HAL) to evaluate, any links would be really appreciated

Thanks,
Pat.

Mike Kelly

unread,
Aug 10, 2012, 7:59:26 AM8/10/12
to api-...@googlegroups.com
On Fri, Aug 10, 2012 at 12:45 PM, Pat Cappelaere <cappe...@gmail.com> wrote:
> Mike,
>
> But not quite off the hook though…
>
> How do you tell your client that the API has "drastically" changed?

When I say a new link relation I mean a new value in the rel property
of a link that replaces the old one, e.g:

<link rel="http://example.com/rels/user-collection" ... />

changing to

<link rel="http://example.com/rels/user-collection#v2" />

an old client is going to tell that the API has drastically changed
because it's going to fail when it attempts to traverse a link
relation that isn't there anymore. We're also considering adding a
'deprecated' property to links in HAL which would give a timestamp
warning that a given link relation was due to be deprecated by that
certain point in time.

> That may be there is another kinda similar but not quite link to consider following? How is that semantic conveyed?

I'm not sure what you mean here can you clarify?

> Wouldn't be extremely dangerous to lead that client through a new link with evolving parameters and end up crashing your server? (not that it would really happen to us)

No, it shouldn't be. If this is a real issue for you, you need to
reconsider your server stack.

> How do you do these different actions with HAL for instance?

change this:

{
_links: {
"self": { "href": "..." },
"http://example.com/rels/user-collection": { "href": "..." }
}
}

to this:

{
_links: {
"self": { "href": "..." },
"http://example.com/rels/user-collection#v2": { "href": "..." }
}
}


> Are you relying on a special implementation of the client?

No, this is pretty much the antithesis of HAL's design. HAL's
deliberately simple in order to avoid making too many assumptions
about the sophistication of the clients, which is key when making
these sorts of value judgements about whether xyz change will be ok
for the clients of the API. The more complicated the type, the more
difficult it is to make a clear value judgement.

> By the way, I am looking for examples of Hypermedia API's (not just HAL) to evaluate, any links would be really appreciated

Ok, here's Mark Nottingham's take on this subject:

http://www.mnot.net/blog/2011/10/25/web_api_versioning_smackdown

Cheers,
M

Daniel Roop

unread,
Aug 10, 2012, 8:01:12 AM8/10/12
to api-...@googlegroups.com
Couple thoughts

- MediaType versioning is less granular than leveraging link relations. -
This is true if you are using a single hypermedia format (e.g., HAL, Collection+JSON) this is not true if you use custom MediaTypes for your domain (like in my example) or a media type that has a variable for schema (e.g., WRML).  This is obviously a design decision, but I want to point out it is possible to version at the MediaType level if your media types defines representations at a granular enough level.

- How is leveraging MediaTypes to version any better than existing approaches like schema declarations? -
Per my previous answer I would point out schema definition is precisely the problem both are trying to solve.  The question is how much influence does the client have over that decision.  If you have a url /person/1234, and I get back a response with schema v1.  Then at some point in the future I get back schema v2, I am broken.  And there is no good way to fix this other than using a uri based versioning approach, because the client had no say in which version of the representation they got back.

If however you leverage content-type negotiation and have the client send the Accept: header with the MediaTypes it supports you can support v1 and v2 and allow the client to specify which one they prefer.  This does of course require a more granular MediaType than HAL or Collection+JSON to take advantage of though.

-Does changing the MediaType also break backwards compatibility-
This may be obvious to everyone but I want to say it because I think it is being ignored.  In any of these situations URI, Link or ContentType there is an underlying assumption that you support the previous way of calling the service until those clients have been migrated.  There is no way to get around this problem.  In a URI based system that means you have to decide to support N number of /v1/ path segments while clients are moving away. In Link based, you have to support N number of resources and links inside your resources.  And for ContentType you have to support N number of versioning of that ContentType while clients migrate.

-Doesn't URL versioning have the same granularity problem as ContentType described above? (I made this one up)-
If you define your version at the higest part of your path (/{version/{resource}/{resourceId}), and clients are expected to rev all the resources together, then I think the answer is yes (example: See ALL APIs on the Web Today).  If you put your version in the resource path and clients are only expected to rev the ones that change (/{resource}-{version}/{resourceId}) then no (see old twitter approach).

-But doesn't that break backwards compatibility? (another made up question)-
I believe a key to ALL of these solutions is that we must agree that breaking backwards compatibility and leveraging versioning is always the last resort.  This actually influences my decision to prefer the two styles i do (Resource and Representation aka URL and ContentType) because I don't want to ever have to version, and when I do I want to limit it to only the places necessary.  Of course you can solve it other ways, but versioning should always be a last resort in my mind.  Typically I have seen developers want to break compatibility because it is easy just to trash the old and launch the new from the serve perspective.  The problem though is that once you no longer control your clients it is a lot harder to get folks to commit to move and be happy about it.  And even in a big enterprise (like where i work) there is cost associated with moving a bunch of clients that rely on your API.  So reducing the risk of that transition by avoid backwards incompatible changes is often cheaper than trashing the old and replacing with new.


- My example of person changing to name is contrived -
Thank you everyone for pointing this out ;-).

-Daniel

Mike Kelly

unread,
Aug 10, 2012, 8:21:29 AM8/10/12
to api-...@googlegroups.com
On Fri, Aug 10, 2012 at 1:01 PM, Daniel Roop <dan...@danielroop.com> wrote:
> Couple thoughts
>
> - MediaType versioning is less granular than leveraging link relations. -
> This is true if you are using a single hypermedia format (e.g., HAL,
> Collection+JSON) this is not true if you use custom MediaTypes for your
> domain (like in my example) or a media type that has a variable for schema
> (e.g., WRML). This is obviously a design decision, but I want to point out
> it is possible to version at the MediaType level if your media types defines
> representations at a granular enough level.

Using a media type with a variable for schema is not versioning via
the media type it's versioning via schema identifiers. This is
equivalent to HAL's use of the profile link relation and media type
parameter.

The only way to achieve granularity via media type identifiers
themselves is to have a custom identifier for each type of resource in
your application, which is even more of an issue wrt media type
identifier proliferation. It also requires the management of a central
organisational registry where these media type identifiers must be
managed vs the distributed nature of using URIs for link relations,
profiles, or schemas. Nobody creates separate media types for each
type of resource in their app, it's not practical and there are no
benefits of doing so.

Using a profile link relation and/or media type parameter is
preferable to a schema, mainly because it's a separate spec that's had
a lot of attention - so why not re-use what we already have?

Further than that though, it's questionable whether an approach that
relies on profiles/schemas as a way of typing resource is a good idea.
Roy coined the terminology underpinning hypermedia APIs and he's been
explicit in describing such typing as a bad practice. The main reason
is that if you are using link relations to drive your application
anyway, then there is really no need to type a resource explicitly
since clients will be able to infer the meaning/type of a resource
according to the context provided by the previous link relation which
led them there. If it makes any difference I can try and find the
quote from Roy where he basically says as much?

> - How is leveraging MediaTypes to version any better than existing
> approaches like schema declarations? -
> Per my previous answer I would point out schema definition is precisely the
> problem both are trying to solve. The question is how much influence does
> the client have over that decision. If you have a url /person/1234, and I
> get back a response with schema v1. Then at some point in the future I get
> back schema v2, I am broken. And there is no good way to fix this other
> than using a uri based versioning approach, because the client had no say in
> which version of the representation they got back.
>
> If however you leverage content-type negotiation and have the client send
> the Accept: header with the MediaTypes it supports you can support v1 and v2
> and allow the client to specify which one they prefer. This does of course
> require a more granular MediaType than HAL or Collection+JSON to take
> advantage of though.

Again, if your application is driven by hypertext this can all be
managed via adding and removing link relations. Link relations are
_the_ interface of a hypermedia API to which clients couple, and that
is where change in the application can and should be managed.

> -Doesn't URL versioning have the same granularity problem as ContentType
> described above? (I made this one up)-
> If you define your version at the higest part of your path
> (/{version/{resource}/{resourceId}), and clients are expected to rev all the
> resources together, then I think the answer is yes (example: See ALL APIs on
> the Web Today). If you put your version in the resource path and clients
> are only expected to rev the ones that change
> (/{resource}-{version}/{resourceId}) then no (see old twitter approach).

Yes, this a reason why versioning via the URI or media types are not
good approaches.

Cheers,
M

Pat Cappelaere

unread,
Aug 10, 2012, 8:46:54 AM8/10/12
to api-...@googlegroups.com
Mike,

On Aug 10, 2012, at 8:21 AM, Mike Kelly <mikeke...@gmail.com> wrote:

> Using a profile link relation and/or media type parameter is
> preferable to a schema, mainly because it's a separate spec that's had
> a lot of attention - so why not re-use what we already have?
>
> Further than that though, it's questionable whether an approach that
> relies on profiles/schemas as a way of typing resource is a good idea.
> Roy coined the terminology underpinning hypermedia APIs and he's been
> explicit in describing such typing as a bad practice. The main reason
> is that if you are using link relations to drive your application
> anyway, then there is really no need to type a resource explicitly
> since clients will be able to infer the meaning/type of a resource
> according to the context provided by the previous link relation which
> led them there. If it makes any difference I can try and find the
> quote from Roy where he basically says as much?

I think that you may want to consider bending a little here :)
There is no question that Hypermedia APIs have some advantages (that need to be highlighted.. and you are doing a great job).
However, I do not think that it is a bad practice to make available your service metadata including schemas to your customers.

I do not mind being lead down an alley but I would rather not be blindfolded.

I cannot think of an enterprise system that would not do that for any reasons. Since it is not a huge deal to provide that capability, it might be of interest to consider leveraging it.

With HTML, you do follow link relations but you can also mark them up to add semantic content to help out during the journey. That semantic content can itself be fully described in a profile document (which beats having to read a pdf).

Just for your consideration.

V/R,
Pat.


Daniel Roop

unread,
Aug 10, 2012, 9:26:16 AM8/10/12
to api-...@googlegroups.com
Using a media type with a variable for schema is not versioning via
the media type it's versioning via schema identifiers.
I am not sure if that matters, the benefit it does give you in my mind is it allows the client to inform the server which schema it understands.  You are right you can do this all through linking but it assumes a "shield" of sorts for all resources.  Where that shield always provides a guaranteed response that never changes with pointers to the different representations.  I imagine this works well if you are assuming you are always in your own API and can control the entry points.  I think where I get hung up here is I want to believe there is a nirvana where our REST APIs can link to each other in the same way the web does.  To get there I don't know if we can be guaranteed that we always have these shileds, and therfore think it is useful to give the client control over representation of schema via content negotiation.
 
Nobody creates separate media types for each
type of resource in their app, it's not practical and there are no
benefits of doing so.

I am going to have to disagree. I believe Hypermedia Types are built to solve a particular problem domain and you should have enough MediaTypes to handle that domain.

AtomPub: RFC5023 
Problem Domain: Publishing Content (of any type)
Types: 
- application/atom+xml
- application/atom+xml;type=entry
- application/atomcat+xml  
- application/atomsvc+xml

HTML: 
Problem Domain: Presentation
Types:
- text/html
- tex/css
- text/javascript
- image/*

These two types have the advantage of solving generic problems.  I think if you are trying to solve a problem domain like say Profile Management, it may require more understanding by the client, and therefore more Content-Types.

The only way to achieve granularity via media type identifiers
themselves is to have a custom identifier for each type of resource in
your application, which is even more of an issue wrt media type
identifier proliferation.
 
This may seem odd, but I agree with you.  You want to avoid a proliferation of media types, but I don't think that translates to a single media type. The other point you make "a representation for every resource" is also spot on.  You should not have a content-type per resource, you should have different representations.  For instance you might have a profile representation.  That representation can be used to show a full profile, a partial profile, a list of profiles etc...But that doesn't mean the client shouldn't know how to handle a specific representation for each resource in your API..  (in order to avoid a tangent I deleted a long example I route up, hopefully this gets my perspective across).

no need to type a resource explicitly
since clients will be able to infer the meaning/type of a resource
according to the context provided by the previous link relation which
led them there.

This is where I also go back and forth (so yes I would be curious to read roy's thoughts on this if you come across the link).  I believe a valuable constraint is that you can provide "hints" at what is on the other end of the link, but this is not a contract, and it feels like an anti-pattern to require this information to be able to handle the resource on the other end.  I say this, acknowledging I have looked to leverage this as a solution multiple times and have talked myself out of it.  This is where i believe drawing form the success of HTML is useful (I think Mike you were the one that didn't so feel free to ignore ;-) ).  A link does give context to the user, but not to the user-agent in the HTML world.  The human understands what should be at the other end by the link given to the href.  The user-agent however has no clue, it just knows to call the link provide all the media-types in the accept header it supports and then render whatever it gets back.  The name of the link has no actual bearing on what is at the other end, and is not really used for context by the user-agent. 

What you are making me think about though is that the user does have the context.  So whatever list is on the other page, the consumer of the user-agent does have knowledge about based on the previous page.  For instance if I see a list of friends, (but not the person I clicked on while this may be bad UX design) the user does have the knowledge of which user he clicked from the previous screen so should have the "state" to understand what this list means based on the link he click.  I will have to mull over this for a bit, to see if using the distinction between user-agent and user is useful here to bring me to your side of this argument.  I will say though that I think because M2M requires more semantic understanding of the resources than "presentation" or "publishing" since the Machine isn't as flexible as the automaton, there is value in more targeted media types for the automatons.  And I would point to the Atom/RSS clients as examples.

-Daniel

M

Pat Cappelaere

unread,
Aug 10, 2012, 9:40:40 AM8/10/12
to api-...@googlegroups.com
Dan,

> This is where I also go back and forth (so yes I would be curious to read roy's thoughts on this if you come across the link). I believe a valuable constraint is that you can provide "hints" at what is on the other end of the link, but this is not a contract, and it feels like an anti-pattern to require this information to be able to handle the resource on the other end. I say this, acknowledging I have looked to leverage this as a solution multiple times and have talked myself out of it. This is where i believe drawing form the success of HTML is useful (I think Mike you were the one that didn't so feel free to ignore ;-) ). A link does give context to the user, but not to the user-agent in the HTML world. The human understands what should be at the other end by the link given to the href. The user-agent however has no clue, it just knows to call the link provide all the media-types in the accept header it supports and then render whatever it gets back. The name of the link has no actual bearing on what is at the other end, and is not really used for context by the user-agent.
>
> What you are making me think about though is that the user does have the context. So whatever list is on the other page, the consumer of the user-agent does have knowledge about based on the previous page. For instance if I see a list of friends, (but not the person I clicked on while this may be bad UX design) the user does have the knowledge of which user he clicked from the previous screen so should have the "state" to understand what this list means based on the link he click. I will have to mull over this for a bit, to see if using the distinction between user-agent and user is useful here to bring me to your side of this argument. I will say though that I think because M2M requires more semantic understanding of the resources than "presentation" or "publishing" since the Machine isn't as flexible as the automaton, there is value in more targeted media types for the automatons. And I would point to the Atom/RSS clients as examples.

What are your thoughts on HTML5+RDFa or Microformats?
Doesn't this add semantic context to a User-Agent?
Isn't that Context itself accessible via a link?
Isn't that Context updatable as needed to inform the User-Agent?
Isn't this how the semantic web works?

Pat.

Daniel Roop

unread,
Aug 10, 2012, 9:57:56 AM8/10/12
to api-...@googlegroups.com
What are your thoughts on HTML5+RDFa or micro formats?
I think they have their place the problem is evolve ability.  Because the client has no way to say which version to use you can't really evolve it.

Doesn't this add semantic context to a User-Agent?
Yes

Isn't that Context itself accessible via a link?
I think you are say the link relation gives me the context to understand the resource. That is true but what if you don't get there via a link but a stored URL?

Isn't that Context updatable as needed to inform the User-Agent?
Not sure I follow

Isn't this how the semantic web works?
Yeah for stuff like micro formats and rdf that is how I think they work.  But you do loose the evolv-ability without ad adding "cruft" to put both versions.  This mat be an acceptable trade off in many situations but I think that will vary.

Steve Klabnik

unread,
Aug 10, 2012, 10:05:52 AM8/10/12
to api-...@googlegroups.com
Oh, about the whole 'super granular media types' approach:
http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

> 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]

Pat Cappelaere

unread,
Aug 10, 2012, 10:10:40 AM8/10/12
to api-...@googlegroups.com

On Aug 10, 2012, at 9:57 AM, Daniel Roop <goof...@gmail.com> wrote:

> What are your thoughts on HTML5+RDFa or micro formats?
> I think they have their place the problem is evolve ability. Because the client has no way to say which version to use you can't really evolve it.

There does not seem to be a problem with evolvability in the semantic world, as far as I can see.

<html xmlns:geo='http//www.w3.org/2003/01/geo/wgs84_pos#'>

</html>

If the geo context changes, the client will surely detect it right away.

>
> Doesn't this add semantic context to a User-Agent?
> Yes
>
> Isn't that Context itself accessible via a link?
> I think you are say the link relation gives me the context to understand the resource. That is true but what if you don't get there via a link but a stored URL?

So I do get in the tag relation semantic info on the element which an actual link reference to the profile itself.
I did not have to create a new mime-type to express that new content in a domain specific manner.
I am still talking HTML at a high level.

>
> Isn't that Context updatable as needed to inform the User-Agent?
> Not sure I follow

That context or profile can be versioned (see html link)

>
> Isn't this how the semantic web works?
> Yeah for stuff like micro formats and rdf that is how I think they work. But you do loose the evolv-ability without ad adding "cruft" to put both versions. This mat be an acceptable trade off in many situations but I think that will vary.

They seem to have addressed the problem in a scalable manner that Roy may accept?
Pat.

Mike Kelly

unread,
Aug 10, 2012, 10:27:08 AM8/10/12
to api-...@googlegroups.com
On typing from the same page:

"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"
> --
> You received this message because you are subscribed to the Google Groups "API Craft" group.
> To unsubscribe from this group, send email to api-craft+...@googlegroups.com.
> Visit this group at http://groups.google.com/group/api-craft?hl=en.
>
>



--
Mike

http://twitter.com/mikekelly85
http://github.com/mikekelly
http://linkedin.com/in/mikekelly123

Pat Cappelaere

unread,
Aug 10, 2012, 10:30:29 AM8/10/12
to api-...@googlegroups.com
Mike,

Just checking? Are you not providing any schemas to your clients to understand the JSON structures that are being passed around?

Pat.

Steve Klabnik

unread,
Aug 10, 2012, 10:32:32 AM8/10/12
to api-...@googlegroups.com
I'm not.

I do provide a media type and/or profile, though.

Mike Kelly

unread,
Aug 10, 2012, 10:39:00 AM8/10/12
to api-...@googlegroups.com
I don't even use a profile, I just describe the structure via the link
relation URI:

http://haltalk.herokuapp.com/rels/user

as seen here (click on one of the docs links):

http://haltalk.herokuapp.com/explorer/hal_browser.html#/users


Steve, do you think that a profile is a form of "type specification"
that Roy is arguing against in the above quote?

Cheers,
M

mca

unread,
Aug 10, 2012, 10:44:49 AM8/10/12
to api-...@googlegroups.com
When I use profiles, I use them as a structured way to add domain specifics (taxonomy, etc.) to an existing domain-agnostic media type design. that makes it possible for 'bots to recognize data points and activate hypermedia affordances similar to the way humans do. That was the point of the ALPS experiement[1].

[1] http://amundsen.com/hypermedia/profiles/

mca


Mike Kelly

unread,
Aug 10, 2012, 10:48:54 AM8/10/12
to api-...@googlegroups.com
Ok, but are they strictly necessary if clients are always approaching
resources via a link relation which can establish this info itself?

Cheers,
M

mca

unread,
Aug 10, 2012, 10:55:53 AM8/10/12
to api-...@googlegroups.com
yes, there can be more than one way to communicate the domain specifics; totally with you on that.

i jumped in to just say that profiles can be used w/o resorting "typing"

Mike Kelly

unread,
Aug 10, 2012, 11:01:56 AM8/10/12
to api-...@googlegroups.com
On Fri, Aug 10, 2012 at 3:55 PM, mca <m...@amundsen.com> wrote:
> yes, there can be more than one way to communicate the domain specifics;
> totally with you on that.
>
> i jumped in to just say that profiles can be used w/o resorting "typing"

So profiles aren't typing? afaict that conflicts with the previous
quote from Roy.. what am I missing?

Cheers,
M

Kevin Swiber

unread,
Aug 10, 2012, 11:06:03 AM8/10/12
to api-...@googlegroups.com
On Fri, Aug 10, 2012 at 9:26 AM, Daniel Roop <dan...@danielroop.com> wrote:
I am going to have to disagree. I believe Hypermedia Types are built to solve a particular problem domain and you should have enough MediaTypes to handle that domain.

AtomPub: RFC5023 
Problem Domain: Publishing Content (of any type)
Types: 
- application/atom+xml
- application/atom+xml;type=entry
- application/atomcat+xml  
- application/atomsvc+xml

HTML: 
Problem Domain: Presentation
Types:
- text/html
- tex/css
- text/javascript
- image/*

These two types have the advantage of solving generic problems.  I think if you are trying to solve a problem domain like say Profile Management, it may require more understanding by the client, and therefore more Content-Types.


Ah, good.  So... "Profile Management" is a very specific domain.  This is where I believe developers/architects start building fine-grained media types (see the Sun Cloud API as an example).

Presentation, Publishing... those are very generic domains.

Siren[1] exposes an object-oriented style API over HTTP, where entities possess both properties and behaviors.  There have been other efforts to this goal, but none (to my knowledge) have fully embraced the benefits of HTTP in their design. (REST defines a lot of these benefits.)  The problem domain it's solving IS an Application Programming Interface.

This means you can build "Profile Management" on top of a media type that helps you expose your API.

Does that make sense?

[1] https://github.com/kevinswiber/siren (Full disclosure: I wrote it.)

--
Kevin Swiber
Projects: https://github.com/kevinswiber
Twitter: @kevinswiber

Kevin Swiber

unread,
Aug 10, 2012, 11:06:05 AM8/10/12
to api-...@googlegroups.com
On Fri, Aug 10, 2012 at 9:26 AM, Daniel Roop <dan...@danielroop.com> wrote:
I am going to have to disagree. I believe Hypermedia Types are built to solve a particular problem domain and you should have enough MediaTypes to handle that domain.

AtomPub: RFC5023 
Problem Domain: Publishing Content (of any type)
Types: 
- application/atom+xml
- application/atom+xml;type=entry
- application/atomcat+xml  
- application/atomsvc+xml

HTML: 
Problem Domain: Presentation
Types:
- text/html
- tex/css
- text/javascript
- image/*

These two types have the advantage of solving generic problems.  I think if you are trying to solve a problem domain like say Profile Management, it may require more understanding by the client, and therefore more Content-Types.

Ah, good.  So... "Profile Management" is a very specific domain.  This is where I believe developers/architects start building fine-grained media types (see the Sun Cloud API as an example).

Presentation, Publishing... those are very generic domains.

Siren[1] exposes an object-oriented style API over HTTP, where entities possess both properties and behaviors.  There have been other efforts to this goal, but none (to my knowledge) have fully embraced the benefits of HTTP in their design. (REST defines a lot of these benefits.)  The problem domain it's solving IS an Application Programming Interface.

This means you can build "Profile Management" on top of a media type that helps you expose your API.

Does that make senes?

mca

unread,
Aug 10, 2012, 11:07:07 AM8/10/12
to api-...@googlegroups.com
what i described here was how i use the profile pattern and i pointed to the example page.

i am of the opinion that what is on that page is not the kind of "typing" you think Roy is talking about.

feel free to point to the examples i provided and show me different.
M

Kevin Swiber

unread,
Aug 10, 2012, 11:17:11 AM8/10/12
to api-...@googlegroups.com
Errr... "Does that make sense?" rather. 

Also, I forgot to include a link to the Sun Cloud API, just to illustrate the difference.


An alternative is something like the example on the Siren GitHub site.

Also, I wanted to point out that none of these techniques are "wrong," per se.  Design isn't so black and white.  I don't think Fielding's work should be seen as the definitive source for how all Web API's should be built.  His opinions, obviously, revolve around the idea of hypermedia API's, because that's his world.  There is a whole set of real-world constraints REST doesn't consider... such as time to market.  :)

Other opinions are certainly worth exploration.

Daniel Roop

unread,
Aug 10, 2012, 11:26:14 AM8/10/12
to api-...@googlegroups.com
Also, I wanted to point out that none of these techniques are "wrong," per se.  Design isn't so black and white.  I don't think Fielding's work should be seen as the definitive source for how all Web API's should be built.  His opinions, obviously, revolve around the idea of hypermedia API's, because that's his world.  There is a whole set of real-world constraints REST doesn't consider... such as time to market.  :)

+1

Daniel Roop

unread,
Aug 10, 2012, 11:31:36 AM8/10/12
to api-...@googlegroups.com
There does not seem to be a problem with evolvability in the semantic world, as far as I can see.
This is a point worth contemplating.  My basic position is that we are going to fail at defining useful "micro-formats" so therefore we need to allow the client to express which version of said micro format they understand.  It is possible you don't need to evolve existing formats as much as I am claiming.  For instance how many times have we had to evolve the hCard.

<html xmlns:geo='http//www.w3.org/2003/01/geo/wgs84_pos#'>

</html>
If the geo context changes, the client will surely detect it right away.
For me the problem isn't the client detecting it, it is the client's ability to influence it.  Since this is only represented in the response, I have no way to say from the client side.  I support xmlns:geo='http://www.w3.org/2012/01/geo/wgs85_pos#" instead of 2003.  I completely understand the client has all the information they need to process it.  But from a "versioning" perspective there is no way for them to say which version of the geo representation they understand.
 
 

Pat.

Daniel Roop

unread,
Aug 10, 2012, 11:39:29 AM8/10/12
to api-...@googlegroups.com
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]
 
"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"

Has anything I have said make you think that I disagree with either of these statements?  I would stress the fact the words used here.  In the first quote Roy states that you should have no "typed" RESOURCES not "typed" REPRESENTATIONS.  I think this is significant, and completely agree.  You shoudl not have "typed" resources.  I should be able to ask for them in numerous representations (pdf, json, xml, collection+json, hal+json, some custom representation specific to some need...)

I will also see your quotes from that page, and raise you a third

A REST API should spend almost all of its descriptive effort in defining the media type(s) used for representing resources and driving application state, or in defining extended relation names and/or hypertext-enabled mark-up for existing standard media types. Any effort spent describing what methods to use on what URIs of interest should be entirely defined within the scope of the processing rules for a media type (and, in most cases, already defined by existing media types). [Failure here implies that out-of-band information is driving interaction instead of hypertext.]

This to me means, you should define media types that are useful for driving the application state on top of the resources that is meaningful to your domain.  

Daniel Roop

unread,
Aug 10, 2012, 11:43:43 AM8/10/12
to api-...@googlegroups.com
Kevin,

my big hangup on all of this, is how does a client express which version of the representation they want.  I must admit I haven't read the siren stuff you have sent as much as I want, but it seems that siren is a single media type (correct?).  So if I call

GET /profile/1234
Accept: application/vnd.siren+json

I will always get back a representation with "type" information decided by the server.  This means that I can not have one version ask for profilev1 and provilev2, even though the response representation includes the type information.  Am I missing something?

On Fri, Aug 10, 2012 at 11:06 AM, Kevin Swiber <ksw...@gmail.com> wrote:

Daniel Roop

unread,
Aug 10, 2012, 11:47:20 AM8/10/12
to api-...@googlegroups.com
So...this is the same thing as siren right?  including the "domain specific information" inside the response.  It doesn't allow the client to express which representation of the the domain specific information it desires.  If I give up on this contraint being useful I completely agree with you guys.  But I am not yet convinced that constraint isn't useful.

To attempt to be clear, the constraint I am describing...
"The client should be able to suggest the domain specific representation they are capable of processing".

mca

unread,
Aug 10, 2012, 11:53:16 AM8/10/12
to api-...@googlegroups.com
the example i linked to is not like siren, AFAIK since my example focuses only on domain specifics, devoid of media-type.

in the example i linked, a profile for describing the problem domain of microblogging is offerred and then applied to a *single* media type (XHTML).  the point of the experiment is to explore the possibility of consistently describing problem domains devoid of a single media type and then applying that domain specific description consistently to more than one media type (i haven't document my attempts on this last point yet).

FWIW, so far, the only tangible examples i have found like this (a single problem domain expressed in multiple hypermedia types) is HAL. maybe i misunderstand HAL on this point. maybe there are more examples of applying the same problem domain semantics to multiple media types.

feel free to point them out to me.

Kevin Swiber

unread,
Aug 10, 2012, 12:02:56 PM8/10/12
to api-...@googlegroups.com
Just catching this now.  This thread is blowin' up!  It might be too late to fork it into a new thread, so I'll just continue...

Bottom line is... significant message structure evolution will break clients.  There's no getting around it (without adding tons of complexity).  To put it in terms of HTML, think about an automated regression testing tool that reads the Web page source and navigates through the site.  If the HTML structure changes significantly, the regression script will break.

Before getting into this, I'd like to separate versioning a media type from versioning an API.  I think we sometimes confuse these two concepts.  (In the fine-grained media type world, they are closer together, but they are still two different concepts.)

The question stands.  How do you create big changes to your API without breaking a hypermedia client?

This assumes...  1) You are absolutely sure that you need this flexibility at all.  2) You need to support new versions quickly.  3) You can't stand leftover cruft in your messaging.  4) You are willing to push the boundaries on comfort zones.  :)

My answer to this (right now, at this time of my life) is to build versioning into your API.

One way to accomplish this is by building version selection into your messaging.

GET /
{
  links: [
    { rel=["http://x.io/rels/version/2", "latest"], href="http://api.x.io/2" }
  ]
}

A client knows it supports version 1, so it looks for the appropriate rel value.  Again... this is a slippery slope.  Make sure it's absolutely necessary.

I've also toyed around with using product tokens in the User-Agent and Server headers.  My advice would be not to head down that path.  There are too many unresolved issues.

I'm certainly open to feedback on this approach.  This is an open sore spot in the hypermedia API universe.  I don't think we can get away without providing guidance on how to resolve it.

Thanks.

On Thu, Aug 9, 2012 at 1:49 PM, Greg Brail <gr...@apigee.com> wrote:
The thing I keep struggling with regarding hypermedia is this:

In a URI-based API (which is what I primarily work with) then the "contract" is the set of URIs and the corresponding resource definitions. So if I add a URI I have not made a breaking change to the contract but if I rename one or change the resource representation in an incompatible way (like you showed) then I have. I change the "major version number" in the URI only when I make a breaking change to the contract.

In a hypermedia-based API, then the "contract" is the set of resource representations, but also the set of link relations on each. I understand that a hypermedia-based API lets the server change the URIs if the client is carefully written to always follow them.

But what happens in a hypermedia API when a link relation is changed in an incompatible way -- it is removed, or renamed, or the resource representation is made incompatible? Isn't that also a breaking change to the contract?


On Thu, Aug 9, 2012 at 7:18 AM, Kevin Swiber <ksw...@gmail.com> wrote:
Put simply, a breaking change to the contract requires a change to the client unless you've developed some super-smart schema-adapting components (which is possible and cool, but potentially expensive).

(Keep in mind this is a very contrived example.  Such a small detail is usually not worth a breaking change.)

Changing...

{ firstName: "Kevin", lastName: "Swiber"}

to...

{ name: { first: "Kevin", last: "Swiber" }

... is potentially a breaking change for API clients, depending on how the contract was written.

With hypermedia contracts, backwards compatibility is very important.  If you were to do this, I think a phased approach is a better way.  Some have mentioned new link relations.  That is one option.  There are more, but really... try not to break compatibility.

If you feel you really need strong versioning, I would recommend using an option that is not purely hypermedia (I believe Greg Brail had a good suggestion).  There are trade-offs, of course.  Every design has its strengths and weaknesses.  I'm putting together a matrix of this in my mind.  I need to commit it to paper.  :)

There is a lot of guidance on URI-driven approaches.  Hypermedia guidance is still evolving, but I'm expecting this to shift over the next few months.  There is room for more than one approach in this arena.  I encourage everyone to be strongly opinionated, but open minded.  I think we do a pretty good job of that on API Craft.  :)


On Thu, Aug 9, 2012 at 9:47 AM, Pat Cappelaere <cappe...@gmail.com> wrote:
Please allow me to keep asking the same question… but since you have another pointed example… I will try again.
You are using for some reason the "complex" custom media type [for which I am still debating the value of :)]
so:
My automaton is dealing with APP1 that sports the custom minted: application/vnd.apicraft;type=Person;version=1

and all of a sudden, APP2 decides to upgrade to: application/vnd.apicraft;type=Person;version=2 (and not support version 1)

[and I have a few more of those to deal with…]

I am a good automaton and I follow the links very faithfully [treat them as completely opaque]
So, how do I know or infer the correct change in the API for one APP? …. 
How do I know that to task, I really need two different parameter types with two different ranges?

I do not see why custom media types help nor how Hypermedia API helps [although Siren might get pretty close… and does not need custom media types]

This is certainly a good exchange
Thanks,
Pat.


On Aug 9, 2012, at 8:52 AM, Daniel Roop <dan...@danielroop.com> wrote:

Since this distinction has been pointed out int he past, I will make it here.  Not all APIs need be "REST" based.  And by REST I mean Hypermedia Driven aka RMM Level 3.   I think if you choose not to go the Hypermedia route (which I wouldn't) then versioning in the URL as described by Greg Brail above is completely workable solution.

Once you drink the Hypermedia Kool-aid it breaks down.  Imagine I have three services, let's call them Catalog, Reservation and Itinerary.  Let's aslo assume that Reservation and Itinerary "link" to catalog information.  If you are providing the version in the URI (ala /v1) You are putting the burden on the client to understand more than one version of the Catalog data you are linking to, if Reservation and Itinerary do not agree on which version you should be linking to.  But this isn't fair, the client is the only one that knows what data he needs from the catalog at the other end of that link, and should ask for the one he wants.  SO my perspective is URL based "version" paths break down when you start linking because
- Puts more burden on the client to understand N number of versions of the same content
- THe alternative is providing which version you care about to all other services which seems slightly unwieldy.

The recommendation I have landed on is that in a Hypermedia Based design I agree with what Mike and mca have been saying (suprise suprise the REST zealots agree ;-)).  I talk about two ways to version a hypermeida API

:Representation Versioning:
This is when the format of your data has changed, but the concept has not.  Imagine I have a /person/{personId} resource.  The person is still a person is still a person.  He has a name.  Maybe it is represented like this
{
    "firstName" : "John",
    "lastName" : "Doe",
    "address" : {
         ...
    }
}

I want want to restructure that, to the following
{
    "name" : {
        "first" : "John",
        "last" : "Doe"
    }
    "address" : {
         ...
    }
}

It would be a backwards incompatible change, and therefore I need to version.  I would do this through the Content-Type.  The easiest way to do this is through adding a version Accept param to your content type. So the original could be application/vnd.apicraft;type=Person;version=1 and the second application/vnd.apicraft;type=Person;version=2. You would typically take advantage of this if you want to change the way some data is represented.  It is easier to imagine this between two completly different formats.  Imagine I have a reservation /reservation/1234, in a hypermedia/rest world I would use content-type negotiation to get the json document, version the xml document vs the pdf.  Same concept.  Typically on the web you see these represented as different links, I actually think this is one of the cases where the human component hurts us.  They have no easy way to say what representation they want simply by clicking a link, so we create different links (and urls) for different content types.  But it isn't required in the m2m world, since the machine can specify which representation it wants.

:Resource Versioning:
This one is where the concept has change.  So building on the previous example let's say, I wanted to have a smaller resource that only dealt with the name, not the address.  This too would be a backwards incompatible change so I need to "version" this somehow.  Since this is a resource model change, I would use the ID for the resource (aka the URL).  But I tend to shy away from "numbers" in this case, because I subscribe to the theory that if you can't name it you don't understand it.  Since you have created a new concept you need to come up with a meaningful name for that concept.  In this case I would call it /person-name/{personId}.  That would just return the name structure, and could even use the same Content-Type as above, but the resource is different and the links to it are probably different.


Some other thoughts:
- I agree with mca that you do not need to make backwards incompatible changes, but I accept this is the tendency for most developers (on both ends) so this is a hard problem to overcome (although not impossible).
- To you original question...IN any of the solutions I have described (or any other's on this thread) I think the answer to your question is no, you don't need to rev the API version.
- We have instituted a rule that (in any of the solutions) that if the "version" is not specified (whether it is /v1/.. or in the content-type) we assume the lowest supported version.  This has the nice side effect of letting you avoid the problem until you need to solve for it (and maybe you won't ever need too).  Google used this in their Google Data API specification as well.
- I do believe that you can draw a lot of information out of how existing Hypermedia Solutions have been implemented, including primarily presentation based ones (like HTML), but I do think M2M creates some unique challenges that HTML does have and vice versa.
- I am starting to wonder if there should be a distinction between a "bot" client and a "remote control" client.  The difference being one is a "crawler link automated program" while the other one has an eventual human on the other side.  I think there is a lot of similarity but I think the "remote control" style has the opportunity to have more "open ended" capabilities since he has a neural network on the other side.

-Daniel

P.S. I love it when this group gets a topic like this...

On Thu, Aug 9, 2012 at 8:13 AM, <chris...@gmail.com> wrote:
On Thu, 9 Aug 2012, Mike Kelly wrote:

I don't think it needs to much more complicated affair than this when
we are talking about APIs. Drawing parallels between human-consumed
HTML web apps and machine-consumed APIs is not a good idea, either -
so don't waste too much time thinking about that.

This sounds like bait, but I'll bite anyway, because I like to
participate in such things. Take this with a bit of I don't live in
the real world salt.

Making a distinction between "machine-consumed APIs" and, well,
everything else seems limiting.

The win from having resources on the (a?) web, using common and
visible media types, and using scrutable URIs is that all sorts of
things, be they machines or humans, can interact with those resources
and do all sorts of stuff.

I'm being a hippy here, but that is, at core, a political statement
about participation and control.

It's no surprise that organizations pigeonholed as enterprisey want to
limit participation and maximize control. In that context, having a
scrutable API means that some yahoo can come along and subvert the
imposed information controls.

Except in extremely rare cases, this is a good thing.

Thinking that has led me to a few conclusions about API designs:

* publish your resource URIs and limit (if not outright remove)
  dependencies between resources
* don't require hypermedia (which is essentially the above sentiment
  repeated)
* Use generic media types (text/plain, text/html, application/json)
  and let the client decide how it chooses to interpret them

and to bring this back to the thread topic:

* Don't worry about versioning. If you've got the above sorted, you
  probably won't need it, and if you find that you do, then perhaps
  what you have is another resource, not a different API.

A profusion of custom media types and a need for versioning is a
hallmark of perhaps thinking a bit too much like RPC or SOAP or
something. That level of complexity is certainly available to you with
a strong REST-over-HTTP API, but is it worth the effort?

If you find that your problem area requires strong and detailed types,
is going to be impacted by slight changes in stucture (thus requiring
versioning) and is encumbered with complexity from trying to manage a
lot of state, it might be worth considering something other than HTTP.

Use HTTP to expose things. With flexibility.

--
Chris Dent                                   http://burningchrome.com/
                                [...]


--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group, send email to api-craft+unsubscribe@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group, send email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft?hl=en.
 
 

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group, send email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft?hl=en.
 
 
--
Kevin Swiber
Projects: https://github.com/kevinswiber
Twitter: @kevinswiber

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group, send email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft?hl=en.
 
 



--
Gregory Brail  |  Technology  |  Apigee

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group, send email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft?hl=en.
 
 



--

Pat Cappelaere

unread,
Aug 10, 2012, 12:31:32 PM8/10/12
to api-...@googlegroups.com
So from what I can glean, we seem to agree (or do we?) that:

1. We all need to provide semantic/contextual information to help clients understand the data structures that may be passed around. There may be several ways of doing this based on your preferred API mime-type (html, json, xml). That's a different thread to explore
2. That contextual information itself can be version-able so that the client can (potentially) evolve with the server
3. A change of version has to be immediately obvious to a client (rather than fall into it)
4. So far there is still no sign of real value added to custom mime types. Early indications tend to show that:
application/vnd.app+json is really bad

if push comes to shove, a better approach would be: application/json; profile="vnd.app"
and you get brownie points if you specify version="1.0"
and describedby="http://myapp.XYZ.com"
for something like: application/json; profile="vnd.app"; version="1.0"; describedby="http://myapp.XYZ.com"

but again, since the client has access to your context info (which may include version), this info is superfluous

is this a good summary?

Thanks,
Pat.


Pat Cappelaere

unread,
Aug 10, 2012, 12:35:31 PM8/10/12
to api-...@googlegroups.com
Kevin,

Have ever seen those custom media types:
application/myapp+atom+xml
or text/vnd.myapp+html for that matter

Just curious/
thanks,
Pat.

Peter Williams

unread,
Aug 10, 2012, 12:43:59 PM8/10/12
to api-...@googlegroups.com
On Fri, Aug 10, 2012 at 10:02 AM, Kevin Swiber <ksw...@gmail.com> wrote:
> One way to accomplish this is by building version selection into your
> messaging.
>
> GET /
> {
> links: [
> { rel=["http://x.io/rels/version/1"], href="http://api.x.io/1" },
> { rel=["http://x.io/rels/version/2", "latest"], href="http://api.x.io/2"
> }
> ]
> }
>
> A client knows it supports version 1, so it looks for the appropriate rel
> value. Again... this is a slippery slope. Make sure it's absolutely
> necessary.
>
> I've also toyed around with using product tokens in the User-Agent and
> Server headers. My advice would be not to head down that path. There are
> too many unresolved issues.

With this model how do you deal with the situation where client A
understands v1 captures the uri `http://api.x.io/1` and passes it to
client B which only understands v2?

The only approach i can think of is to provide a link to every
resource that is logically equivalent to the current resource (ie, one
link for each version) in every representation generated by the api.
That way client B could GET the v1 resource and see that it has a v2
equivalent and navigate to that supported version of the resource.
This is certainly possible but it is effectively a just an awkward
implementation of content negotiation. We are basically just saying
that each resource has exactly one representation and then using links
(and extra round trips) to find the representation we actually want.

Many incremental changes/improvement can be made to apis using the
addition of new link relations and properties. We should definitely
use that approach when possible. However, when you are introducing
representations that have a significantly different structure you need
content negotiation. You can either implement it yourself or you can
use http's built in (and fairly bad ass) content negotiation. Or you
could do both.

Peter
barelyenough.org

justin kruger

unread,
Aug 10, 2012, 12:56:06 PM8/10/12
to api-...@googlegroups.com
At a very basic idea an api is an Interface, and in software
Interfaces are contracts.

Another contract we have at the API level is an API token.

In some worlds like facebook, the product is in such evolution that it
would be hard for a facebook API engineer to enter into a 10 year
contract, or even a 2 year contract. I bet facebook can only really
say that their API might be stable for about 3 months.

Netflix on the other hand has entered into contracts with TV
manufactures and in those cased the API needs to hold up for 5-7
years. Versioning in the Netflix world allows them to hold true on
their contracts while innovating.

I think any API should default to the latest version of the contract,
and using it all of the time will always resort to the latest version,
however, i do believe that once you have a consumer that would like a
stable version of the API some expectations need to be set around how
long that API will be stable.

Using a version number in a device that is say 5 years old, seems
silly if in year 2 you discover a security exploit and you need to fix
it, because those... good urls are not going to change right? What
will happen is all of that semantic goodness you tried to architect
will get thrown out when you need to map all v1.56 requests to
v1.56.03. If you just made the changes at the API KEY level and
allowed the manufacturer/ consumer to upgrade via an upgrade pannel,
that same key could map to any version of the API, not just the one
you define.

I think the API key pattern also works for facebook as it allows a
user with an app that consumes it to choose which version to use.

The key to remember is that both the API and it's version are separate
contracts. I have yet to implement an API this way, but.. I'd like to
it seems to make sense.
> --
> You received this message because you are subscribed to the Google Groups "API Craft" group.
> To unsubscribe from this group, send email to api-craft+...@googlegroups.com.
> Visit this group at http://groups.google.com/group/api-craft?hl=en.
>
>



--
--
--
Justin Kruger
Social Media Software Engineer -
San Francisco, CA

--
http://twitter.com/jdavid
http://www.linkedin.com/in/jdavid

Peter Williams

unread,
Aug 10, 2012, 12:56:19 PM8/10/12
to api-...@googlegroups.com
On Fri, Aug 10, 2012 at 10:31 AM, Pat Cappelaere <cappe...@gmail.com> wrote:
> So from what I can glean, we seem to agree (or do we?) that:

Who is we?

> 1. We all need to provide semantic/contextual information to help clients understand the data structures that may be passed around. There may be several ways of doing this based on your preferred API mime-type (html, json, xml). That's a different thread to explore

I'd say there is definitely *not* consensus on this this point.
(Assuming that by "provide" you mean "provide in http responses".)

> 2. That contextual information itself can be version-able so that the client can (potentially) evolve with the server

I'd say there is also not a general consensus on this point. (Though i
tend to agree.)

> 3. A change of version has to be immediately obvious to a client (rather than fall into it)

Still no consensus. :) (The best changes are ones existing clients
don't even notice.)

> 4. So far there is still no sign of real value added to custom mime types. Early indications tend to show that:
> application/vnd.app+json is really bad

I'd say there is significant evidence that this approach works rather
well. We can argue over whether it is the best approach, but is has
*no* functional problems and has been in use by a fair number of
systems for a fairly long time.

> if push comes to shove, a better approach would be: application/json; profile="vnd.app"
> and you get brownie points if you specify version="1.0"
> and describedby="http://myapp.XYZ.com"
> for something like: application/json; profile="vnd.app"; version="1.0"; describedby="http://myapp.XYZ.com"

These are all effectively just the domain/app specific mime type
approach implemented in a less well supported (by intermediates and
app frameworks) way.

Peter
barelyenough.org

Kevin Swiber

unread,
Aug 10, 2012, 1:22:17 PM8/10/12
to api-...@googlegroups.com
On Fri, Aug 10, 2012 at 12:43 PM, Peter Williams <pe...@barelyenough.org> wrote:
On Fri, Aug 10, 2012 at 10:02 AM, Kevin Swiber <ksw...@gmail.com> wrote:
> One way to accomplish this is by building version selection into your
> messaging.
>
> GET /
> {
>   links: [
>     { rel=["http://x.io/rels/version/1"], href="http://api.x.io/1" },
>     { rel=["http://x.io/rels/version/2", "latest"], href="http://api.x.io/2"
> }
>   ]
> }
>
> A client knows it supports version 1, so it looks for the appropriate rel
> value.  Again... this is a slippery slope.  Make sure it's absolutely
> necessary.
>
> I've also toyed around with using product tokens in the User-Agent and
> Server headers.  My advice would be not to head down that path.  There are
> too many unresolved issues.

With this model how do you deal with the situation where client A
understands v1 captures the uri `http://api.x.io/1` and passes it to
client B which only understands v2?

I'm not sure I fully understand the scenario.  Is "client A" acting as a proxy to the service for "client B?" If "client B" can't figure it out, it breaks.

 
The only approach i can think of is to provide a link to every
resource that is logically equivalent to the current resource (ie, one
link for each version) in every representation generated by the api.
That way client B could GET the v1 resource and see that it has a v2
equivalent and navigate to that supported version of the resource.
This is certainly possible but it is effectively a just an awkward
implementation of content negotiation. We are basically just saying
that each resource has exactly one representation and then using links
(and extra round trips) to find the representation we actually want.

That seems really awkward, and I'm not sure what the use case is for switching between versions.
 
Many incremental changes/improvement can be made to apis using the
addition of new link relations and properties. We should definitely
use that approach when possible. However, when you are introducing
representations that have a significantly different structure you need
content negotiation. You can either implement it yourself or you can
use http's built in (and fairly bad ass) content negotiation. Or you
could do both.

If by "significantly different," you mean a new format altogether (like PDF instead of text/plain), then I agree with using content negotiation.
 

Pat Cappelaere

unread,
Aug 10, 2012, 1:23:29 PM8/10/12
to api-...@googlegroups.com

On Aug 10, 2012, at 12:56 PM, Peter Williams <pe...@barelyenough.org> wrote:

> On Fri, Aug 10, 2012 at 10:31 AM, Pat Cappelaere <cappe...@gmail.com> wrote:
>> So from what I can glean, we seem to agree (or do we?) that:
>
> Who is we?

I was just trying to summarize where I thought this group was converging on because the thread is becoming fairly long and I am loosing it. Please try to summarize for me as we go.

>
>> 1. We all need to provide semantic/contextual information to help clients understand the data structures that may be passed around. There may be several ways of doing this based on your preferred API mime-type (html, json, xml). That's a different thread to explore
>
> I'd say there is definitely *not* consensus on this this point.
> (Assuming that by "provide" you mean "provide in http responses".)

Well, are you the only one not doing it?
HTML does it with Microformats, Microdata, HTML5+RDFa… and other profile patterns…
XML does it with schemas
JSON has JSON-Schema…
Siren with Profile management…
[not sure about HAL… no semantic info found provided examples: http://haltalk.herokuapp.com/rels/user
so it cannot really be used in a more complex enterprise system]

>
>> 3. A change of version has to be immediately obvious to a client (rather than fall into it)
>
> Still no consensus. :) (The best changes are ones existing clients
> don't even notice.)

That's not realistic. There will be cases that changes are inevitable and will break clients.

>
>> 4. So far there is still no sign of real value added to custom mime types. Early indications tend to show that:
>> application/vnd.app+json is really bad
>
> I'd say there is significant evidence that this approach works rather
> well. We can argue over whether it is the best approach, but is has
> *no* functional problems and has been in use by a fair number of
> systems for a fairly long time.

I was pointed by IT people to problems in organizations that use highly secured proxies/firewalls… they will not punch holes for all those custom media types (especially if they keep changing)…
and having the burden on the developer side to keep mucking with your settings to debug the apis.
So it seemed that the second recommendation was far more palatable while still redundant.

Pat.

Kevin Swiber

unread,
Aug 10, 2012, 1:25:45 PM8/10/12
to api-...@googlegroups.com
Just an add-on... I neglected to mention what I felt was somewhat obvious.  If versioning is absolutely necessary and the client isn't responsible for choosing a preference from a list of versions, the easiest hypermedia approach is just to provide a different root URL for your entry point.

Pat Cappelaere

unread,
Aug 10, 2012, 1:38:08 PM8/10/12
to api-...@googlegroups.com
Kevin,

Have you ever tackled any more significant API than dealing with obvious resources that do not require any semantic context?
[there may be a better way to phrase this…]
If I am a geo service, I need to know about projection assumption, lat/long order…
Thanks,
Pat.

Peter Williams

unread,
Aug 10, 2012, 1:43:17 PM8/10/12
to api-...@googlegroups.com
On Fri, Aug 10, 2012 at 11:23 AM, Pat Cappelaere <cappe...@gmail.com> wrote:
>>> 1. We all need to provide semantic/contextual information to help clients understand the data structures that may be passed around. There may be several ways of doing this based on your preferred API mime-type (html, json, xml). That's a different thread to explore
>>
>> I'd say there is definitely *not* consensus on this this point.
>> (Assuming that by "provide" you mean "provide in http responses".)
>
> Well, are you the only one not doing it?
> HTML does it with Microformats, Microdata, HTML5+RDFa… and other profile patterns…
> XML does it with schemas
> JSON has JSON-Schema…
> Siren with Profile management…
> [not sure about HAL… no semantic info found provided examples: http://haltalk.herokuapp.com/rels/user
> so it cannot really be used in a more complex enterprise system]

I was not speaking for myself on this point. Several people have
expressed the idea that the client has some context before it makes a
request and that it can use that context to decide how to process the
response.

>> (The best changes are ones existing clients
>> don't even notice.)
>
> That's not realistic. There will be cases that changes are inevitable and will break clients.

I agree that we may not always achieve backwards compatible
improvements. But it is often achievable and it we, as api developers,
should strive for it at all times. If we tried we could achieve a lot
more often than we currently do.

If our mean time to incompatible change was 10 years would it even be
worth having this conversation?

> I was pointed by IT people to problems in organizations that use highly secured proxies/firewalls… they will not punch holes for all those custom media types (especially if they keep changing)…

I suppose that there might be networks some place in the world that
block rare media types but after implementing several apis that are
used by very large, stodgy and enterprisey organizations i have yet to
encounter any such issues. I think this argument falls into the FUD
category.

> and having the burden on the developer side to keep mucking with your settings to debug the apis.

This is a fair critique. Not one that, imo, rises to the level of
disqualifying the solution, though.

> So it seemed that the second recommendation was far more palatable while still redundant.

I'll try FUD argument myself now. :) Are the caches in intermediates
and/or in your http library going to really treat
`application/json;version=1` and `application/json;version=2` as
different? (I am not even sure that according to the HTTP spec they
should.). And are you going to be able to easily implement handing out
different responses based on a mime type parameter?

Peter
barelyenough.org

Pat Cappelaere

unread,
Aug 10, 2012, 1:54:07 PM8/10/12
to api-...@googlegroups.com

On Aug 10, 2012, at 1:43 PM, Peter Williams <pe...@barelyenough.org> wrote:

> On Fri, Aug 10, 2012 at 11:23 AM, Pat Cappelaere <cappe...@gmail.com> wrote:
>>>> 1. We all need to provide semantic/contextual information to help clients understand the data structures that may be passed around. There may be several ways of doing this based on your preferred API mime-type (html, json, xml). That's a different thread to explore
>>>
>>> I'd say there is definitely *not* consensus on this this point.
>>> (Assuming that by "provide" you mean "provide in http responses".)
>>
>> Well, are you the only one not doing it?
>> HTML does it with Microformats, Microdata, HTML5+RDFa… and other profile patterns…
>> XML does it with schemas
>> JSON has JSON-Schema…
>> Siren with Profile management…
>> [not sure about HAL… no semantic info found provided examples: http://haltalk.herokuapp.com/rels/user
>> so it cannot really be used in a more complex enterprise system]
>
> I was not speaking for myself on this point. Several people have
> expressed the idea that the client has some context before it makes a
> request and that it can use that context to decide how to process the
> response.

If that's the case, they need to speak up. If the client needs out-of-band info and rely on a pdf spec, then this would be a disqualifier for me

>
>>> (The best changes are ones existing clients
>>> don't even notice.)
>>
>> That's not realistic. There will be cases that changes are inevitable and will break clients.
>
> I agree that we may not always achieve backwards compatible
> improvements. But it is often achievable and it we, as api developers,
> should strive for it at all times. If we tried we could achieve a lot
> more often than we currently do.

Sure but this is not the world I live in.

>
> If our mean time to incompatible change was 10 years would it even be
> worth having this conversation?
>
>> I was pointed by IT people to problems in organizations that use highly secured proxies/firewalls… they will not punch holes for all those custom media types (especially if they keep changing)…
>
> I suppose that there might be networks some place in the world that
> block rare media types but after implementing several apis that are
> used by very large, stodgy and enterprisey organizations i have yet to
> encounter any such issues. I think this argument falls into the FUD
> category.

Nope this sounds real to me. Please do not blow it off unless you can really back it up. We do have to go through security firewalls. I do not see why we ought to make it harder on ourselves if solution 2 has the same meaning.

>
>> and having the burden on the developer side to keep mucking with your settings to debug the apis.
>
> This is a fair critique. Not one that, imo, rises to the level of
> disqualifying the solution, though.

Fair but I have seen the value either.

>
>> So it seemed that the second recommendation was far more palatable while still redundant.
>
> I'll try FUD argument myself now. :) Are the caches in intermediates
> and/or in your http library going to really treat
> `application/json;version=1` and `application/json;version=2` as
> different? (I am not even sure that according to the HTTP spec they
> should.). And are you going to be able to easily implement handing out
> different responses based on a mime type parameter?

We certainly will need to respond with different resource representations as needed.
I am not sure that we will support:
text/myapp+html
application/vnd.myapp+json
application/vnd.myapp+atom+xml
unless there is a legitimate need for it. Still trying to find it.

Thanks,
Pat.



Peter Williams

unread,
Aug 10, 2012, 2:05:39 PM8/10/12
to api-...@googlegroups.com
On Fri, Aug 10, 2012 at 11:22 AM, Kevin Swiber <ksw...@gmail.com> wrote:
> I'm not sure I fully understand the scenario. Is "client A" acting as a
> proxy to the service for "client B?" If "client B" can't figure it out, it
> breaks.

Lets say i have a order system, an accounting system and a warehouse
(inventory/shipping) system. These systems work together to help me
run my business.

* the order system, after accepting a new order, notifies the
warehouse api of the order to be shipped and the accounting api of the
revenue by passing the uri of the order to each
* the warehouse uses that uri to figure out what items to actually
ship (because people can remove items from the order right up until
the moment the order actually ships, a la Amazon).
* Once the order has shipped the warehouse notifies the accounting
api that the order has been shipped (so that the revenue can be
realized)

Consider the following scenario:

1. we release a new incompatible version of the order api (but we
continue to pass v1 uris to both the warehouse and accounting so
nothing breaks)
2. we update the warehouse to support v2 of the order api and change
it so that we use the v2 uri for the warehouse
3. we stop realizing revenue until we update accounting to support the
v2 order api because when the warehouse says `/v2/order/42` shipped
accounting goes and fetches that resource but doesn't know how to
interpret the representation it gets back.

In this example, if we update accounting first we might be able to
roll things out more incrementally but the larger the number of
interlinked systems the more likely we are going to end up with a
version dead lock between some of them.

Peter
barelyenough.org

Daniel Roop

unread,
Aug 10, 2012, 3:00:15 PM8/10/12
to api-...@googlegroups.com
1. We all need to provide semantic/contextual information to help clients understand the data structures that may be passed around.  There may be several ways of doing this based on your preferred API mime-type (html, json, xml).  That's a different thread to explore

I don't know that you NEED to, but I can see potential value in it.

4. So far there is still no sign of real value added to custom mime types.  Early indications tend to show that:
This is where i strongly disagree.  Should application/atom+xml not exist because application/xml   exists?  the Atom mime type builds on top of xml (and the xml format even encourages this behavior by declare that +xml is a standard for extending the format to have semantic meaning.

REST in Practice (a great book on this topic) also recommends app specific Media Types.  If you haven't read the book I would highly recommend it.

since the client has access to your context info (which may include version), this info is superfluous
You are suggesting that because in the response the client recieves contains a reference to a schema, they don't need a say in the version that is returned?  I think I am missing something.
 

On Fri, Aug 10, 2012 at 12:31 PM, Pat Cappelaere <cappe...@gmail.com> wrote:
So from what I can glean, we seem to agree (or do we?) that:



3. A change of version has to be immediately obvious to a client (rather than fall into it)
4. So far there is still no sign of real value added to custom mime types.  Early indications tend to show that:
        application/vnd.app+json  is really bad

        if push comes to shove, a better approach would be: application/json; profile="vnd.app"
        and you get brownie points if you specify version="1.0"
        and describedby="http://myapp.XYZ.com"
        for something like: application/json; profile="vnd.app"; version="1.0"; describedby="http://myapp.XYZ.com"

        but again, since the client has access to your context info (which may include version), this info is superfluous

is this a good summary?

Thanks,
Pat.

Pat Cappelaere

unread,
Aug 10, 2012, 3:09:54 PM8/10/12
to api-...@googlegroups.com
On Aug 10, 2012, at 3:00 PM, Daniel Roop <dan...@danielroop.com> wrote:

1. We all need to provide semantic/contextual information to help clients understand the data structures that may be passed around.  There may be several ways of doing this based on your preferred API mime-type (html, json, xml).  That's a different thread to explore

I don't know that you NEED to, but I can see potential value in it.
Needs quite a bit in that area.  As soon as you have to deal with specific, non trivial data, you really need to be careful about explaining what you mean (not unlike any semantic effort out there)


4. So far there is still no sign of real value added to custom mime types.  Early indications tend to show that:
This is where i strongly disagree.  Should application/atom+xml not exist because application/xml   exists?  the Atom mime type builds on top of xml (and the xml format even encourages this behavior by declare that +xml is a standard for extending the format to have semantic meaning.

REST in Practice (a great book on this topic) also recommends app specific Media Types.  If you haven't read the book I would highly recommend it.

LOL.  I do read a few books occasionally. Thanks for the pointer. I am talking about application specific mime-types.
Again, have you seen any indication of people out there exposing their resources and using:
application/vnd.myapp+atom+xml
or creating web pages with domain specific content as text/vnd.myapp+html

Just curious.


since the client has access to your context info (which may include version), this info is superfluous
You are suggesting that because in the response the client recieves contains a reference to a schema, they don't need a say in the version that is returned?  I think I am missing something.

Yes.  Since any serious client accessing any serious service would have access to that context information that would also contain version info in some form or another.

So why would you also need to specify a custom media type for serious RESTful applications.  Sorry for drilling on this.
Pat.

Peter Williams

unread,
Aug 10, 2012, 3:50:49 PM8/10/12
to api-...@googlegroups.com
On Fri, Aug 10, 2012 at 1:09 PM, Pat Cappelaere <cappe...@gmail.com> wrote:
> Again, have you seen any indication of people out there exposing their
> resources and using:
> application/vnd.myapp+atom+xml
> or creating web pages with domain specific content as text/vnd.myapp+html

Github is the only public API i am aware of that uses vendor media
types.[1] (Anyone else away of other public examples?) I do it on a
regular basis, as do several others that frequent the rest-discuss
mailing list. The APIs i work on are not available to the public, but
they are regularly utilized by clients developed and run by our
customers.

[1]: http://developer.github.com/v3/mime/

Peter
barelyenough.org

Pat Cappelaere

unread,
Aug 10, 2012, 4:02:00 PM8/10/12
to api-...@googlegroups.com
Peter,
But that was not my question. Look at the mime-types.

Regardless Is Github a best practice we ought to follow for reasons I have given?
They still do support original mime-type application/json
[VERSIONing is introduced in the mime-type itself.]
They do not have any "semantically challenged" data types.

If you have domain specific content in an HTML page, do you use text/vnd.app+html ?
If you extend Atom to output domain specific resources, do you use application/vnd.app+atom+xml ?

Thanks,
Pat.

Kevin Swiber

unread,
Aug 10, 2012, 4:03:03 PM8/10/12
to api-...@googlegroups.com
On Fri, Aug 10, 2012 at 11:43 AM, Daniel Roop <dan...@danielroop.com> wrote:
Kevin,

my big hangup on all of this, is how does a client express which version of the representation they want.  I must admit I haven't read the siren stuff you have sent as much as I want, but it seems that siren is a single media type (correct?).  So if I call

GET /profile/1234
Accept: application/vnd.siren+json

I will always get back a representation with "type" information decided by the server.  This means that I can not have one version ask for profilev1 and provilev2, even though the response representation includes the type information.  Am I missing something?

I mentioned some options in another strand of this thread[1].

There are options such as hypermedia-driven negotiation (i.e., having the client select from a list of versions the server provides)... or just using a completely different URL starting point.

Whatever method... For big ol' changes, I think it makes sense to have the client choose which version they want to interact with, whether that's by hypermedia or client developer making a decision at design time.

13protons

unread,
Aug 10, 2012, 4:31:16 PM8/10/12
to api-...@googlegroups.com
My take on versioning is to literally interpret the previous posts about "you should version if you introduce incompatible features". Adding new vocabulary to your api that doesn't break what's already in place wouldn't need a customer facing version increment, even though you'd probably want to track that progress internally with a minor v #. 

-Alan

On Wednesday, August 8, 2012 3:47:19 AM UTC-4, Indumathi wrote:
Is it necessary to include version if I m introducing new urls for resources in my API

Happy to hear any suggestions over this.

Thanks
Indu

Jack Repenning

unread,
Aug 10, 2012, 4:37:28 PM8/10/12
to api-...@googlegroups.com
On Aug 10, 2012, at 1:31 PM, 13protons <al...@13protons.com> wrote:

My take on versioning is to literally interpret the previous posts about "you should version if you introduce incompatible features". Adding new vocabulary to your api that doesn't break what's already in place wouldn't need a customer facing version increment, even though you'd probably want to track that progress internally with a minor v #. 

Agreed, that "introducing new URLs for resources" sounds like a "compatible change," and shouldn't cause you to roll your version number: all code that formerly worked with your API still does (right? or did you mean something else?).

Agreed, that you'll want to keep track of anything you change.

But disagree, I think, that the way to track that is "minor version number." I think tracking that via version control is sufficient. In any case, if your tracking scheme includes some such concept as a "minor version number," whatever that is it should not be embedded in the URLs. "Tracking internally," pretty much by definition, means tracking things the users don't need to care about.

Jack Repenning





Mike Kelly

unread,
Aug 11, 2012, 5:27:02 AM8/11/12
to api-...@googlegroups.com


On 10 Aug 2012, at 18:23, Pat Cappelaere <cappe...@gmail.com> wrote:

>
>>
>>> 1. We all need to provide semantic/contextual information to help clients understand the data structures that may be passed around. There may be several ways of doing this based on your preferred API mime-type (html, json, xml). That's a different thread to explore
>>
>> I'd say there is definitely *not* consensus on this this point.
>> (Assuming that by "provide" you mean "provide in http responses".)
>
> Well, are you the only one not doing it?
> HTML does it with Microformats, Microdata, HTML5+RDFa… and other profile patterns…
> XML does it with schemas
> JSON has JSON-Schema…
> Siren with Profile management…
> [not sure about HAL… no semantic info found provided examples: http://haltalk.herokuapp.com/rels/user
> so it cannot really be used in a more complex enterprise system]

HAL absolutely can be used in a "complex enterprise system" (afaik GEICO have a huge project built on top of it being worked on by large dev team).

If the HTML page at the /rels/user URI is not complex enough then you could also serve a JSON shema document or similar from that URI too.

HAL also has profiles, check out the Internet-Draft:

http://tools.ietf.org/html/draft-kelly-json-hal-03

Cheers,
M
It is loading more messages.
0 new messages