Forward/Backward versioning, media-types, etc

"Kevin Duffey [email protected] [rest-discuss]" <[email protected]> Sat, 16 Aug 2014 20:48:40 -0700
Newsgroups gmane.comp.web.services.rest
Message-ID <[email protected]>
---2079400718-122398558-1408247320=:90082
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable

Hi all,

I've been reading up quite a bit on versioning, HATEOAS, forward/backward c=
ompatibility changes and versioning, etc with REST APIs. Some recent docs a=
re suggesting that more people are using versioning in the URI but only for=
 major version changes of the entire API and update the version very rarely=
. I fall into the camp that the resource URI should not be versioned, inste=
ad using the Accept header and version the media-type (conneg).=A0

I do have a couple of questions though around all this.

From some stuff I've read, it sounded like if I have a version 1 XML docume=
nt, with say <a><b>data</b></a>, and that was public, and then I wanted to =
add a new element to that doc (representation) (e.g. <a><b/><c/></a> or <a>=
<b><c/></b></a>), existing clients should not break because they would simp=
ly ignore the newly added element. However, I am seeing something somewhat =
different, in that we support JSON and XML, and in some cases, we're seeing=
 exceptions when the new document is trying to be marshaled into a POJO obj=
ect. I should say that we provide an XSD document that is used by our serve=
r side as well as clients to generate POJOs. We do so with Python and Java =
presently, but I assume any language could take our XSD and generate POJOs,=
 then use those when marshaling/un-marshaling representations. So it seems,=
 at least with XML, there may be a way (I don't know off hand) to "relax" t=
he requirement for newly added elements to match the generated POJO
 objects, such that a client with our first version could actually receive =
the 2nd version document, but would only see the elements that their first =
version POJO understood during the marshaling process. Hope that makes sens=
e. Anyway, I am confused if this is how it should be, with both XML and JSO=
N, or if the exception we're seeing means that our clients MUST indicate ve=
rsion 2 of the representation?

I think the right answer is that ALL of our resources should always require=
 the Accept header to include the version of the document, and from day one=
, it should be v1, so that when v2 comes out, existing clients are still us=
ing v1 (and we return v1 to them), but those clients that know about v2, ca=
n update their clients to request the v2 representation. At least from all =
that I've read, this seems safer than assuming a client using our XSDs to g=
enerate POJOs to use in their language, will get a properly marshaled v2 re=
presentation within a v1 POJO.

Along similar lines.. when we add new items to an existing doc, then it's c=
orrect to bump the version value to get the new representation.. right? Tha=
t is, we're currently working through a beta program and we're taking custo=
mer feedback to adjust/add/fix/remove/etc various API resource representati=
ons. During this cycle, some of our customers are still using version 1, so=
me moved to version 2, and we're working on version 3 now. Is it "ok" to ke=
ep bumping the version in this case? At some point we'll release a GA and w=
hatever version that is, stays in GA. However, our goal is to move to a mor=
e rapid release schedule, such that we may be adding features (new resource=
s) along with updating (extending/adding to) existing resources (their repr=
esentations). As we do this, I assume we should be bumping the versions of =
the specific resource representations that change (be it add, change or rem=
ove elements from the representation).. does that make sense?
---2079400718-122398558-1408247320=:90082
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit




<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
</head>






 
<body style="background-color: #fff;">
<span style="display:none">&nbsp;</span>

<!--~-|**|PrettyHtmlStartT|**|-~-->
<div id="ygrp-mlmsg" style="position:relative;">
  <div id="ygrp-msg" style="z-index: 1;">
<!--~-|**|PrettyHtmlEndT|**|-~-->

    <div id="ygrp-text" >
      
      
      <p><div style="color:#000;background-color:#fff;font-family:HelveticaNeue, Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif;font-size:12pt;"><div id="yiv6191446839"><div><div style="color: rgb(0, 0, 0);font-family: HelveticaNeue, 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif;font-size: 12pt;background-color: rgb(255, 255, 255);"><div id="yiv6191446839yui_3_16_0_6_1408125632107_19">Hi all,</div><div id="yiv6191446839yui_3_16_0_6_1408125632107_19"><br id="yiv6191446839yui_3_16_0_1_1408125632107_28546"></div><div id="yiv6191446839yui_3_16_0_6_1408125632107_19" style="color: rgb(0, 0, 0);font-size: 16px;font-family: HelveticaNeue, 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif;font-style: normal;background-color: transparent;">I've been readi
 ng up quite a bit on versioning, HATEOAS, forward/backward compatibility changes and versioning, etc with REST APIs. Some recent docs are suggesting that
 more people are using versioning in the URI but only for major version changes of the entire API and update the version very rarely. I fall into the camp that the resource URI should not be versioned, instead using the Accept header and version the media-type
 (conneg).&nbsp;</div><div id="yiv6191446839yui_3_16_0_6_1408125632107_19" style="color: rgb(0, 0, 0);font-size: 16px;font-family: HelveticaNeue, 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif;font-style: normal;background-color: transparent;"><br id="yiv6191446839yui_3_16_0_1_1408125632107_28548"></div><div id="yiv6191446839yui_3_16_0_6_1408125632107_19" style="color: rgb(0, 0, 0);font-size: 16px;font-family: HelveticaNeue, 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif;font-style: normal;background-color: transparent;">I do have a couple of questions though around all this.</div><div id="yiv6191446839yui_3_16_0_6_1408125632107_19" style="color: rgb(0, 0, 0);font-size: 16px;font-family: HelveticaNeue, 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', s
 ans-serif;font-style: normal;background-color: transparent;"><br id="yiv6191446839yui_3_16_0_1_1408125632107_28550"></div><div id="yiv6191446839yui_3_16_0_6_1408125632107_19" style="color: rgb(0, 0, 0);font-size: 16px;font-family: HelveticaNeue, 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif;font-style: normal;background-color: transparent;">From some stuff I've read, it sounded like if I have a version 1 XML document, with say &lt;a&gt;&lt;b&gt;data&lt;/b&gt;&lt;/a&gt;, and that was public, and then I wanted to add a new element to that doc (representation) (e.g. &lt;a&gt;&lt;b/&gt;&lt;c/&gt;&lt;/a&gt; or &lt;a&gt;&lt;b&gt;&lt;c/&gt;&lt;/b&gt;&lt;/a&gt;), existing clients should not break because they would simply ignore the newly added element. However, I am seeing som
 ething somewhat different, in that we support JSON and XML, and in some cases, we're seeing exceptions when the new document is trying to be marshaled into a POJO object. I should say that we provide an XSD document that is used by our server side as well as clients to generate POJOs. We do
 so with Python and Java presently, but I assume any language could take our XSD and generate POJOs, then
 use those when marshaling/un-marshaling representations. So it seems, at least with XML, there may be a way (I don't know off hand) to "relax" the requirement for newly added elements to match the generated POJO objects, such that a client with our first version could actually receive the 2nd version document, but would only see the elements that their first version POJO understood during the marshaling process. Hope that makes sense. Anyway, I am confused if this is how it should be, with both XML and JSON, or if the exception we're seeing means that our clients MUST indicate version 2 of the representation?</div><div id="yiv6191446839yui_3_16_0_6_1408125632107_19" style="color: rgb(0, 0, 0);font-size: 16px;font-family: HelveticaNeue, 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', 
 sans-serif;font-style: normal;background-color: transparent;"><br id="yiv6191446839yui_3_16_0_1_1408125632107_28603"></div><div id="yiv6191446839yui_3_16_0_6_1408125632107_19" style="color: rgb(0, 0, 0);font-size: 16px;font-family: HelveticaNeue, 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif;font-style: normal;background-color: transparent;">I think the right answer is that ALL of our resources should always require the Accept header to include the version of the document, and from day one, it should be v1, so that when v2 comes out, existing clients are still using v1 (and we return v1 to them), but those clients that know about v2, can update their clients to request the v2 representation. At least from all that I've read, this seems safer than assuming a client using
  our XSDs to generate POJOs to use in their language, will get a properly marshaled v2 representation within a v1 POJO.</div><div id="yiv6191446839yui_3_16_0_6_1408125632107_19" style="color: rgb(0, 0, 0);font-size: 16px;font-family: HelveticaNeue, 'Helvetica Neue', Helvetica, Arial,
 'Lucida Grande', sans-serif;font-style: normal;background-color: transparent;"><br id="yiv6191446839yui_3_16_0_1_1408125632107_28660"></div><div id="yiv6191446839yui_3_16_0_6_1408125632107_19" style="color: rgb(0, 0, 0);font-size: 16px;font-family: HelveticaNeue, 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif;font-style: normal;background-color: transparent;">Along similar lines.. when we add new items to an existing doc, then it's correct to bump the version value to get the new representation.. right? That is, we're currently working through a beta program and we're taking customer feedback to adjust/add/fix/remove/etc various API resource representations. During this cycle, some of our customers are still using version 1, some moved to version 2, and we're working on v
 ersion 3 now. Is it "ok" to keep bumping the version in this case? At some point we'll release a GA and whatever version that is, stays in GA. However, our goal
 is to move to a more rapid release schedule, such that we may be adding features (new resources) along with
 updating (extending/adding to) existing resources (their representations). As we do this, I assume we should be bumping the versions of the specific resource representations that change (be it add, change or remove elements from the representation).. does that make sense?</div><div id="yiv6191446839yui_3_16_0_6_1408125632107_19" style="color: rgb(0, 0, 0);font-size: 16px;font-family: HelveticaNeue, 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif;font-style: normal;background-color: transparent;"><br id="yiv6191446839yui_3_16_0_1_1408125632107_28662"></div><div id="yiv6191446839yui_3_16_0_6_1408125632107_19" style="color: rgb(0, 0, 0);font-size: 16px;font-family: HelveticaNeue, 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif;font-style: normal;background-col
 or: transparent;"><br></div><div id="yiv6191446839yui_3_16_0_6_1408125632107_19" style="color: rgb(0, 0, 0);font-size: 16px;font-family: HelveticaNeue,
 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif;font-style: normal;background-color: transparent;"><br id="yiv6191446839yui_3_16_0_1_1408125632107_28605"></div><div id="yiv6191446839yui_3_16_0_6_1408125632107_19" style="color: rgb(0, 0, 0);font-size: 16px;font-family: HelveticaNeue, 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif;font-style: normal;background-color: transparent;"><br></div></div></div></div></div></p>

    </div>
     

    <!--~-|**|PrettyHtmlStart|**|-~-->
    <div style="color: #fff; height: 0;">__._,_.___</div>

          
  
 

    
    <div style="clear:both"> </div>

    <div id="fromDMARC" style="margin-top: 10px;">
        <hr style="height:2px ; border-width:0; color:#E3E3E3; background-color:#E3E3E3;">
        Posted by: Kevin Duffey &lt;[email protected]&gt;        <hr style="height:2px ; border-width:0; color:#E3E3E3; background-color:#E3E3E3;">
     </div>
    <div style="clear:both"> </div>

    <table cellspacing=4px style="margin-top: 10px; margin-bottom: 10px; color: #2D50FD;">
      <tbody>
        <tr>
          <td style="font-size: 12px; font-family: arial; font-weight: bold; padding: 7px 5px 5px;"  >
                          <a style="text-decoration: none; color: #2D50FD" href="https://groups.yahoo.com/neo/groups/rest-discuss/conversations/messages/19703;_ylc=X3oDMTJxMjQ0aDAwBF9TAzk3MzU5NzE0BGdycElkAzQzMTkyNTUEZ3Jwc3BJZAMxNzA1NzAxMDE0BG1zZ0lkAzE5NzAzBHNlYwNmdHIEc2xrA3JwbHkEc3RpbWUDMTQwODI0NzUwMw--?act=reply&messageNum=19703">Reply via web post</a>
                      </td>
          <td>&bull;</td>
          <td style="font-size: 12px; font-family: arial; padding: 7px 5px 5px;" >
            <a href="mailto:[email protected]?subject=Re%3A%20Forward%2FBackward%20versioning%2C%20media-types%2C%20etc" style="text-decoration: none; color: #2D50FD;">
               Reply to sender            </a>
          </td>
          <td>&bull;</td>
          <td style="font-size: 12px; font-family: arial; padding: 7px 5px 5px;">
            <a href="mailto:[email protected]?subject=Re%3A%20Forward%2FBackward%20versioning%2C%20media-types%2C%20etc" style="text-decoration: none; color: #2D50FD">
              Reply to group            </a>
          </td>
          <td>&bull;</td>
          <td style="font-size: 12px; font-family: arial; padding: 7px 5px 5px;" >
            <a href="https://groups.yahoo.com/neo/groups/rest-discuss/conversations/newtopic;_ylc=X3oDMTJlY2lhZnMyBF9TAzk3MzU5NzE0BGdycElkAzQzMTkyNTUEZ3Jwc3BJZAMxNzA1NzAxMDE0BHNlYwNmdHIEc2xrA250cGMEc3RpbWUDMTQwODI0NzUwMw--" style="text-decoration: none; color: #2D50FD">Start a New Topic</a>
          </td>
          <td>&bull;</td>
          <td style="font-size: 12px; font-family: arial; padding: 7px 5px 5px;color: #2D50FD;" >
                            <a href="https://groups.yahoo.com/neo/groups/rest-discuss/conversations/topics/19703;_ylc=X3oDMTM2Z2VzbDdyBF9TAzk3MzU5NzE0BGdycElkAzQzMTkyNTUEZ3Jwc3BJZAMxNzA1NzAxMDE0BG1zZ0lkAzE5NzAzBHNlYwNmdHIEc2xrA3Z0cGMEc3RpbWUDMTQwODI0NzUwMwR0cGNJZAMxOTcwMw--" style="text-decoration: none; color: #2D50FD;">Messages in this topic</a>
                (1)
                      </td>
        </tr>
      </tbody>
    </table>

        

<!------- Start Nav Bar ------>




 

<!-- |**|begin egp html banner|**| -->
<div id="ygrp-vital" style="background-color: #f2f2f2; font-family: Verdana; font-size: 10px; margin-bottom: 10px; padding: 10px;">

    <span id="vithd" style="font-weight: bold; color: #333; text-transform: uppercase; "><a href="https://groups.yahoo.com/neo/groups/rest-discuss/info;_ylc=X3oDMTJlZmFnZTN0BF9TAzk3MzU5NzE0BGdycElkAzQzMTkyNTUEZ3Jwc3BJZAMxNzA1NzAxMDE0BHNlYwN2dGwEc2xrA3ZnaHAEc3RpbWUDMTQwODI0NzUwMw--" style="text-decoration: none;">Visit Your Group</a></span>

     <ul style="list-style-type: none; margin: 0; padding: 0; display: inline;">
            <li style="border-right: 1px solid #000; font-weight: 700; display: inline; padding: 0 5px; margin-left: 0;">
      <span class="cat"><a href="https://groups.yahoo.com/neo/groups/rest-discuss/members/all;_ylc=X3oDMTJmaWtqdjg2BF9TAzk3MzU5NzE0BGdycElkAzQzMTkyNTUEZ3Jwc3BJZAMxNzA1NzAxMDE0BHNlYwN2dGwEc2xrA3ZtYnJzBHN0aW1lAzE0MDgyNDc1MDM-" style="text-decoration: none;">New Members</a></span>
      <span class="ct" style="color: #ff7900;">1</span>
    </li>
                                              </ul>
  </div>


<div id="ft" style="font-family: Arial; font-size: 11px; margin-top: 5px; padding: 0 2px 0 0; clear: both;">
  <a href="https://groups.yahoo.com/neo;_ylc=X3oDMTJkZGM2ZmlnBF9TAzk3NDc2NTkwBGdycElkAzQzMTkyNTUEZ3Jwc3BJZAMxNzA1NzAxMDE0BHNlYwNmdHIEc2xrA2dmcARzdGltZQMxNDA4MjQ3NTAz" style="float: left;"><img src="http://l.yimg.com/ru/static/images/yg/img/email/new_logo/logo-groups-137x15.png" height="15" width="137" alt="Yahoo! Groups" style="border: 0;"/></a>
  <div style="color: #747575; float: right;"> &bull; <a href="https://info.yahoo.com/privacy/us/yahoo/groups/details.html" style="text-decoration: none;">Privacy</a> &bull; <a href="mailto:[email protected]?subject=Unsubscribe" style="text-decoration: none;">Unsubscribe</a> &bull; <a href="https://info.yahoo.com/legal/us/yahoo/utos/terms/" style="text-decoration: none;">Terms of Use</a> </div>
</div>
<br>

<!-- |**|end egp html banner|**| -->

  </div> <!-- ygrp-msg -->

 
  <!-- Sponsor -->
  <!-- |**|begin egp html banner|**| -->
  <div id="ygrp-sponsor" style="width:160px; float:right; clear:none; margin:0 0 25px 0; background: #fff;">

<!-- Start Recommendations -->
<div id="ygrp-reco">
     </div>
<!-- End Recommendations -->



  </div>   <!-- |**|end egp html banner|**| -->

  <div style="clear:both; color: #FFF; font-size:1px;">.</div>
</div>

  <img src="http://geo.yahoo.com/serv?s=97359714/grpId=4319255/grpspId=1705701014/msgId=19703/stime=1408247503" width="1" height="1"> <br>

<img src="http://y.analytics.yahoo.com/fpc.pl?ywarid=515FB27823A7407E&a=10001310322279&js=no&resp=img" width="1" height="1"> 

<div style="color: #fff; height: 0;">__,_._,___</div>
<!--~-|**|PrettyHtmlEnd|**|-~-->

</body>

<!--~-|**|PrettyHtmlStart|**|-~-->
<head>
  <style type="text/css">
  <!--
  #ygrp-mkp {
  border: 1px solid #d8d8d8;
  font-family: Arial;
  margin: 10px 0;
  padding: 0 10px;
}

#ygrp-mkp hr {
  border: 1px solid #d8d8d8;
}

#ygrp-mkp #hd {
  color: #628c2a;
  font-size: 85%;
  font-weight: 700;
  line-height: 122%;
  margin: 10px 0;
}

#ygrp-mkp #ads {
  margin-bottom: 10px;
}

#ygrp-mkp .ad {
  padding: 0 0;
}

#ygrp-mkp .ad p {
  margin: 0;
}

#ygrp-mkp .ad a {
  color: #0000ff;
  text-decoration: none;
}
  #ygrp-sponsor #ygrp-lc {
  font-family: Arial;
}

#ygrp-sponsor #ygrp-lc #hd {
  margin: 10px 0px;
  font-weight: 700;
  font-size: 78%;
  line-height: 122%;
}

#ygrp-sponsor #ygrp-lc .ad {
  margin-bottom: 10px;
  padding: 0 0;
}

  #actions {
    font-family: Verdana;
    font-size: 11px;
    padding: 10px 0;
  }

  #activity {
    background-color: #e0ecee;
    float: left;
    font-family: Verdana;
    font-size: 10px;
    padding: 10px;
  }

  #activity span {
    font-weight: 700;
  }

  #activity span:first-child {
    text-transform: uppercase;
  }

  #activity span a {
    color: #5085b6;
    text-decoration: none;
  }

  #activity span span {
    color: #ff7900;
  }

  #activity span .underline {
    text-decoration: underline;
  }

  .attach {
    clear: both;
    display: table;
    font-family: Arial;
    font-size: 12px;
    padding: 10px 0;
    width: 400px;
  }

  .attach div a {
    text-decoration: none;
  }

  .attach img {
    border: none;
    padding-right: 5px;
  }

  .attach label {
    display: block;
    margin-bottom: 5px;
  }

  .attach label a {
    text-decoration: none;
  }
  
  blockquote {
    margin: 0 0 0 4px;
  }

  .bold {
    font-family: Arial;
    font-size: 13px;
    font-weight: 700;
  }

  .bold a {
    text-decoration: none;
  }

  dd.last p a {
    font-family: Verdana;
    font-weight: 700;
  }

  dd.last p span {
    margin-right: 10px;
    font-family: Verdana;
    font-weight: 700;
  }

  dd.last p span.yshortcuts {
    margin-right: 0;
  }

  div.attach-table div div a {
    text-decoration: none;
  }

  div.attach-table {
    width: 400px;
  }

  div.file-title a, div.file-title a:active, div.file-title a:hover, div.file-title a:visited {
    text-decoration: none;
  }

  div.photo-title a, div.photo-title a:active, div.photo-title a:hover, div.photo-title a:visited {
    text-decoration: none;
  }

  div#ygrp-mlmsg #ygrp-msg p a span.yshortcuts {
    font-family: Verdana;
    font-size: 10px;
    font-weight: normal;
  }

  .green {
    color: #628c2a;
  }

  .MsoNormal {
    margin: 0 0 0 0;
  }

  o {
    font-size: 0;
  }

  #photos div {
    float: left;
    width: 72px;
  }

  #photos div div {
    border: 1px solid #666666;
    height: 62px;
    overflow: hidden;
    width: 62px;
  }

  #photos div label {
    color: #666666;
    font-size: 10px;
    overflow: hidden;
    text-align: center;
    white-space: nowrap;
    width: 64px;
  }

  #reco-category {
    font-size: 77%;
  }

  #reco-desc {
    font-size: 77%;
  }

  .replbq {
    margin: 4px;
  }

  #ygrp-actbar div a:first-child {
   /* border-right: 0px solid #000;*/
    margin-right: 2px;
    padding-right: 5px;
  }

  #ygrp-mlmsg {
    font-size: 13px;
    font-family: Arial, helvetica,clean, sans-serif;
    *font-size: small;
    *font: x-small;
  }

  #ygrp-mlmsg table {
    font-size: inherit;
    font: 100%;
  }

  #ygrp-mlmsg select, input, textarea {
    font: 99% Arial, Helvetica, clean, sans-serif;
  }

  #ygrp-mlmsg pre, code {
    font:115% monospace;
    *font-size:100%;
  }

  #ygrp-mlmsg * {
    line-height: 1.22em;
  }

  #ygrp-mlmsg #logo {
    padding-bottom: 10px;
  }


  #ygrp-msg p a {
    font-family: Verdana;
  }

  #ygrp-msg p#attach-count span {
    color: #1E66AE;
    font-weight: 700;
  }

  #ygrp-reco #reco-head {
    color: #ff7900;
    font-weight: 700;
  }

  #ygrp-reco {
    margin-bottom: 20px;
    padding: 0px;
  }

  #ygrp-sponsor #ov li a {
    font-size: 130%;
    text-decoration: none;
  }

  #ygrp-sponsor #ov li {
    font-size: 77%;
    list-style-type: square;
    padding: 6px 0;
  } 

  #ygrp-sponsor #ov ul {
    margin: 0;
    padding: 0 0 0 8px;
  }

  #ygrp-text {
    font-family: Georgia;
  }

  #ygrp-text p {
    margin: 0 0 1em 0;
  }

  #ygrp-text tt {
    font-size: 120%;
  }

  #ygrp-vital ul li:last-child {
    border-right: none !important; 
  } 
  -->
  </style>
</head>

<!--~-|**|PrettyHtmlEnd|**|-~-->
</html>
<!-- end group email -->


---2079400718-122398558-1408247320=:90082--