<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#ffffff" text="#000000">
    On 10/12/2011 07:55 PM, Mark Nottingham wrote:<br>
    <blockquote cite="mid:721C1EB7-AA33-4FE4-ABD5-1B7C91728762@mnot.net"
      type="cite">
      <blockquote type="cite">
        <pre wrap="">The duplication of effort can be solved by having an intermediary do the translation. Repose already does this.
</pre>
      </blockquote>
      <pre wrap="">
That's where there be dragons. Inferring that the user wants to go to version N of the resource because they request version M of the representation conflates format versioning with API versioning. They are not the same.
</pre>
    </blockquote>
    <small>What do you mean by "version N of the resource"? We version
      languages to describe things, not the things themselves. Usually
      the resources are real world instances in our business domain that
      only know their current real-world state. We come up with
      different recipes to project that state onto to a representation
      if it makes sense. <br>
    </small>
    <blockquote cite="mid:721C1EB7-AA33-4FE4-ABD5-1B7C91728762@mnot.net"
      type="cite">
      <pre wrap=""></pre>
      <blockquote type="cite">
        <pre wrap="">We deal with the correspondence between versioned URIs and media types by adopting a single structure rule that is non-RESTful: /v1/foo and /v2/foo are implicitly understood to be variants of /foo .
</pre>
      </blockquote>
      <pre wrap="">
Why? If you wipe the slate clean and start a /v2 API, the whole idea is that it's not backwards-compatible with v1. Predicating it on v1 just ties your hands.
</pre>
    </blockquote>
    <small>The API may break backwards compatibility as a whole, but
      contain resources that continue to make sense. Breaking backwards
      compatibility does not require a burn-the-bridges break with the
      past. Here's an example:<br>
      <br>
      Lets say in v1 of my API I have servers and they have IPs .
      Resources are like so:<br>
      <a class="moz-txt-link-freetext" href="http://cloud.net/servers/456">http://cloud.net/servers/456</a><br>
      <a class="moz-txt-link-freetext" href="http://cloud.net/servers/456/ips">http://cloud.net/servers/456/ips</a><br>
      <a class="moz-txt-link-freetext" href="http://cloud.net/ip/200.100.99.98">http://cloud.net/ip/200.100.99.98</a><br>
      <br>
      I realize I want to model multiple NICs and that a server's IPs
      aren't direct children of the server any more, but require their
      NIC:<br>
    </small><small><a class="moz-txt-link-freetext" href="http://cloud.net/servers/456">http://cloud.net/servers/456</a><br>
    </small><small><a class="moz-txt-link-freetext" href="http://cloud.net/servers/456/eth0/ips">http://cloud.net/servers/456/eth0/ips</a><br>
    </small><small><a class="moz-txt-link-freetext" href="http://cloud.net/servers/456/eth1/ips">http://cloud.net/servers/456/eth1/ips</a><br>
    </small><small><a class="moz-txt-link-freetext" href="http://cloud.net/ips/200.100.99.98">http://cloud.net/ips/200.100.99.98</a><br>
      <br>
      This breaks backwards compatibility of the API as servers with
      multiple NICs no longer  honor the WADL template </small><small><a class="moz-txt-link-freetext" href="http://cloud.net/server/">http://cloud.net/server/</a>{server_number}/ips
      . Such servers would also only support the v2 media type </small><small>app/vnd.server;version=2</small><small>
      at </small><small><a class="moz-txt-link-freetext" href="http://cloud.net/server/">http://cloud.net/server/</a>{server_number} as now
      we split the IP list up under each listed NIC .Note if I have a
      server with one NIC, it can continue to work fine with either v1
      or v2.</small><br>
    <small><br>
      In these cases, the resource meaning of </small><small><a class="moz-txt-link-freetext" href="http://cloud.net/server/456">http://cloud.net/server/456</a>
      and</small><small> <a class="moz-txt-link-freetext" href="http://cloud.net/ips/200.100.99.98">http://cloud.net/ips/200.100.99.98</a> isn't
      version dependent. <br>
      <br>
    </small><small>If a server 789 is a new multi-NIC server, an old v1
      client would still see it listed at </small><small><a class="moz-txt-link-freetext" href="http://cloud.net/servers">http://cloud.net/servers</a>,
      but a GET against </small><small><a class="moz-txt-link-freetext" href="http://cloud.net/servers/789">http://cloud.net/servers/789</a>
      that accepts only </small><small>app/vnd.server;version=1 would
      have to get a 406 response and a choices document showing it only
      supports </small><small>app/vnd.server;version=2. If this seems
      harsh, note that I can only get such a server if I'm using a
      multi-NIC aware v2 client to create/configure it. <br>
      <br>
      If server 876 is single NIC server, then it will work fine,
      yielding representations in either API version.</small><br>
    <small><br>
    </small><br>
    <blockquote cite="mid:721C1EB7-AA33-4FE4-ABD5-1B7C91728762@mnot.net"
      type="cite">
      <blockquote type="cite">
        <pre wrap="">This is similar to /bar.xml and /bar.json being implicitly related to /bar . That's not RESTful either, but if you ever want to see the JSON in a browser, you live with it.
</pre>
      </blockquote>
      <pre wrap="">
*Shrug* I'm not really interested in RESTfulness for its own sake, so that's OK.
</pre>
    </blockquote>
    <small>I wish that HTML and browsers would let you specify the media
      type or accepts header with a link: <br>
       <a href="/bar" type="application/json">bar as
      json</a><br>
      This, combined with actually using status code 300 and
      agent-driven content negotiation by sending an html menu would be
      so much cleaner.<br>
    </small><small></small><br>
    <br>
  </body>
</html>