Loading ...
Sorry, an error occurred while loading the content.

API versioning

Expand Messages
  • erewh0n
    When versioning an API a common approach is to specify version information in the URI. I m curious how others have solved (or would solve) this problem from a
    Message 1 of 13 , Jan 7, 2013
    • 0 Attachment
      When versioning an API a common approach is to specify version information in the URI. I'm curious how others have solved (or would solve) this problem from a RESTful perspective. I'm aware of the recommendation to use the content-type header for specifying version information, however I am concerned that routing and load balancing features would suffer. So for example if we versioned an API with api.example.com/orders/v1 and api.example.com/orders/v2, it is straightforward to route requests for v1 to one set of web servers and route requests for v2 to another set of web servers. Facilitating this based on HTTP headers is more complex and requires more "plumbing". This is also true in-code, where URI mapping semantics are first-order concerns for many libraries (e.g. using Web API or ServiceStack, etc, it is straightforward to map URIs to controllers or contracts).

      Anyway, it would be interesting to hear other people's feedback on this issue.

      Thanks.
    • Mike Kelly
      If you have to do it, you may want to look at versioning using a subdomain i.e: v1.api.example.com/orders that ll let you take advantage of DNS, should you
      Message 2 of 13 , Jan 7, 2013
      • 0 Attachment
        If you have to do it, you may want to look at versioning using a subdomain i.e:


        that'll let you take advantage of DNS, should you need to split the traffic in the future.

        Cheers,
        M


        On Mon, Jan 7, 2013 at 11:39 PM, erewh0n <keith.hassen@...> wrote:
         

        When versioning an API a common approach is to specify version information in the URI. I'm curious how others have solved (or would solve) this problem from a RESTful perspective. I'm aware of the recommendation to use the content-type header for specifying version information, however I am concerned that routing and load balancing features would suffer. So for example if we versioned an API with api.example.com/orders/v1 and api.example.com/orders/v2, it is straightforward to route requests for v1 to one set of web servers and route requests for v2 to another set of web servers. Facilitating this based on HTTP headers is more complex and requires more "plumbing". This is also true in-code, where URI mapping semantics are first-order concerns for many libraries (e.g. using Web API or ServiceStack, etc, it is straightforward to map URIs to controllers or contracts).

        Anyway, it would be interesting to hear other people's feedback on this issue.

        Thanks.




        --
        Mike

        http://twitter.com/mikekelly85
        http://github.com/mikekelly
        http://linkedin.com/in/mikekelly123
      • Eric J. Bowman
        ... If you re using a whole different language to describe your API each time it changes, you re missing the point of REST... ... Likewise, if you need a
        Message 3 of 13 , Jan 7, 2013
        • 0 Attachment
          "erewh0n" wrote:
          >
          > I'm aware of the recommendation to use the content-type header for
          > specifying version information...
          >

          If you're using a whole different "language" to describe your API each
          time it changes, you're missing the point of REST...

          >
          > So for example if we versioned an API with api.example.com/orders/v1
          > and api.example.com/orders/v2, it is straightforward to route requests
          > for v1 to one set of web servers and route requests for v2 to another
          > set of web servers.
          >

          Likewise, if you need a whole 'nother server farm each time your API is
          modified...

          >
          > This is also true in-code, where URI mapping semantics are first-
          > order concerns for many libraries (e.g. using Web API or ServiceStack,
          > etc, it is straightforward to map URIs to controllers or contracts).
          >

          Aha! HTTP frameworks do encourage solving problems at the protocol
          layer. What they aren't much good for, unfortunately, is thinking in
          hypertext. I don't want to say there's no versioning in REST, in fact
          if I PUT an existing image to my server, the old image is renamed not
          removed; there's a "versioned" API inherent in this strategy.

          As to API versioning, do just that, version your hypertext API -- not
          your URLs, your conceptual mappings aren't changing. Neither should
          your media type -- I mostly use XHTML to define APIs, that's as detailed
          a description of the actual API as intermediaries need in order to
          participate in the communication (which they won't do if you're just
          "re-labeling" XHTML as custom, versioned media types to conneg around
          proper hypertext API design).

          Anything else is up to the user-agent to work out. This is actually
          easier for m2m than h2m; a v1 m2m client should already ignore any
          hypertext it doesn't understand, rolling out v2 can then re-use any
          non-deprecated bits of the API already present plus the new stuff, and
          ignore the deprecated stuff. Can't it?

          -Eric
        • Keith Hassen
          ... Hmm. I wouldn t say I m using a different language , I m very explicitly using the Content-Type to negotiate the media format (say
          Message 4 of 13 , Jan 7, 2013
          • 0 Attachment
            > If you're using a whole different "language" to describe your API each
            > time it changes, you're missing the point of REST...


            Hmm. I wouldn't say I'm using a different "language", I'm very explicitly using the Content-Type to negotiate the media format (say "vnd.example.com.order+json"). I can imagine a breaking change to the representation of the resource at the URI api.example.com/order/[order-id] that can be represented by returning a Content-Type of "vnd.example.com.order+json;version=2" or something similar. Similarly, clients can request that specific version of the resource with the Accept header set correctly.

            This seems to be a recommended practice that I've encountered in reading about RESTful implementations.

            > Anything else is up to the user-agent to work out. This is actually
            > easier for m2m than h2m; a v1 m2m client should already ignore any
            > hypertext it doesn't understand, rolling out v2 can then re-use any
            > non-deprecated bits of the API already present plus the new stuff, and
            > ignore the deprecated stuff. Can't it?

            Not always, at least not in my experience. :) I have found that while breaking changes don't happen often, they *do* happen. Add to this the possibility of different types of API consumers that start off implementing your APIs the same way, but slowly (or rapidly!) diverge over time. In some cases new resources (and thus new URIs) will suffice, but in other cases what we are doing is very specifically *evolving* the resource representation to accommodate new requirements.


            On 2013-01-07, at 10:37 PM, Eric J. Bowman wrote:

            > "erewh0n" wrote:
            >>
            >> I'm aware of the recommendation to use the content-type header for
            >> specifying version information...
            >>
            >
            > If you're using a whole different "language" to describe your API each
            > time it changes, you're missing the point of REST...
            >
            >>
            >> So for example if we versioned an API with api.example.com/orders/v1
            >> and api.example.com/orders/v2, it is straightforward to route requests
            >> for v1 to one set of web servers and route requests for v2 to another
            >> set of web servers.
            >>
            >
            > Likewise, if you need a whole 'nother server farm each time your API is
            > modified...
            >
            >>
            >> This is also true in-code, where URI mapping semantics are first-
            >> order concerns for many libraries (e.g. using Web API or ServiceStack,
            >> etc, it is straightforward to map URIs to controllers or contracts).
            >>
            >
            > Aha! HTTP frameworks do encourage solving problems at the protocol
            > layer. What they aren't much good for, unfortunately, is thinking in
            > hypertext. I don't want to say there's no versioning in REST, in fact
            > if I PUT an existing image to my server, the old image is renamed not
            > removed; there's a "versioned" API inherent in this strategy.
            >
            > As to API versioning, do just that, version your hypertext API -- not
            > your URLs, your conceptual mappings aren't changing. Neither should
            > your media type -- I mostly use XHTML to define APIs, that's as detailed
            > a description of the actual API as intermediaries need in order to
            > participate in the communication (which they won't do if you're just
            > "re-labeling" XHTML as custom, versioned media types to conneg around
            > proper hypertext API design).
            >
            > Anything else is up to the user-agent to work out. This is actually
            > easier for m2m than h2m; a v1 m2m client should already ignore any
            > hypertext it doesn't understand, rolling out v2 can then re-use any
            > non-deprecated bits of the API already present plus the new stuff, and
            > ignore the deprecated stuff. Can't it?
            >
            > -Eric
          • Eric J. Bowman
            ... Perfectly good HTTP API practice; REST, not so much. The point of media types is to provide loose coupling based on shared understanding of how the
            Message 5 of 13 , Jan 7, 2013
            • 0 Attachment
              Keith Hassen wrote:
              >
              > This seems to be a recommended practice that I've encountered in
              > reading about RESTful implementations.
              >

              Perfectly good HTTP API practice; REST, not so much. The point of
              media types is to provide loose coupling based on shared understanding
              of how the representation is to be decoded. Not tight coupling based
              on interpreting the content of the representation. I've never seen an
              order API that couldn't be represented as HTML; despite any number of
              variations on this theme (or versions within), the media type doesn't
              vary between more order APIs on the Web than I can count.

              REST has no notion of resource "type" let alone of exposing same on the
              wire, so I've never understood why this solution is so prevalent in REST
              discussions. Just media types, which are agnostic as to what "type" of
              resource is being represented (with rare exceptions as parameters).

              >
              > > Anything else is up to the user-agent to work out. This is actually
              > > easier for m2m than h2m; a v1 m2m client should already ignore any
              > > hypertext it doesn't understand, rolling out v2 can then re-use any
              > > non-deprecated bits of the API already present plus the new stuff,
              > > and ignore the deprecated stuff. Can't it?
              >
              > Not always, at least not in my experience. :) I have found that
              > while breaking changes don't happen often, they *do* happen. Add to
              > this the possibility of different types of API consumers that start
              > off implementing your APIs the same way, but slowly (or rapidly!)
              > diverge over time. In some cases new resources (and thus new URIs)
              > will suffice, but in other cases what we are doing is very
              > specifically *evolving* the resource representation to accommodate
              > new requirements.
              >

              Then design for graceful degradation (or progressive enhancement) using
              client-side feature detection. Just saying there's no need to swing
              the conneg hammer to turn this particular screw.

              -Eric
            • Jørn Wildt
              Hi Eric ... wire, so I ve never understood why this solution is so prevalent in REST discussions. Just media types, which are agnostic as to what type of
              Message 6 of 13 , Jan 8, 2013
              • 0 Attachment
                Hi Eric

                > REST has no notion of resource "type" let alone of exposing same on the
                wire, so I've never understood why this solution is so prevalent in REST
                discussions. Just media types, which are agnostic as to what "type" of
                resource is being represented (with rare exceptions as parameters).

                I remember your stance on this from previous discussions. And, yes, a "sales order" or what ever other "type" you need can certainly be represented as (X)HTML. Sure, I am in no way questioning that.

                My question is though - from where does the client get the information it needs to extract, say, the order sum, delivery address, order lines quantity and so on from the generic payload?

                Let me expand with an example:

                - A client of mine sends me a link to a sales order and I want to import that into my local ERP system.

                - If the sales order is only available in (X)HTML, JSON or similar generic media type, how would I then be able to understand the content in enough detail to import it?

                - If the sales order was available in ATOM, I could at least import it as a document having a title and some content. But, okay, you can do that with (X)HTML too - albeit not with JSON and XML.

                - If the sales order was available in an even more domain specific media type, I could do an even better import of data.

                - ... and so on for various levels of domain specific media types ...

                Having a domain specific media type does although not imply any specific "type" of the resource itself - it only says "this particular resource can (also) be represented as XXX" - where XXX is an official application specific media type, for instance vCard or vCal which would allow the client to derive contact and calendar information from a resource - without making *any* kind of assumption about the underlying "type" of the it.

                Actually, I would argue that a generic media type is more "typed" than a domain specific media type. Okay, that sounds like rubbish, I know - but let me explain:

                - as I stated above, a domain specific media type lets you derived useful information from a resource without making any assumptions about its underlying type.

                - whereas a generic media type forces the client to magically assume the resource has a specific type with specific properties you can extract from the generic payload.

                Well, that is my current view on this issue ... and I have been swinging back and forth between your viewpoint and the above viewpoint during the last couple of years :-) Still open for new inputs!

                Thanks, Jørn


                On Tue, Jan 8, 2013 at 6:57 AM, Eric J. Bowman <eric@...> wrote:
                 

                Keith Hassen wrote:
                >
                > This seems to be a recommended practice that I've encountered in
                > reading about RESTful implementations.
                >

                Perfectly good HTTP API practice; REST, not so much. The point of
                media types is to provide loose coupling based on shared understanding
                of how the representation is to be decoded. Not tight coupling based
                on interpreting the content of the representation. I've never seen an
                order API that couldn't be represented as HTML; despite any number of
                variations on this theme (or versions within), the media type doesn't
                vary between more order APIs on the Web than I can count.

                REST has no notion of resource "type" let alone of exposing same on the
                wire, so I've never understood why this solution is so prevalent in REST
                discussions. Just media types, which are agnostic as to what "type" of
                resource is being represented (with rare exceptions as parameters).


                >
                > > Anything else is up to the user-agent to work out. This is actually
                > > easier for m2m than h2m; a v1 m2m client should already ignore any
                > > hypertext it doesn't understand, rolling out v2 can then re-use any
                > > non-deprecated bits of the API already present plus the new stuff,
                > > and ignore the deprecated stuff. Can't it?
                >
                > Not always, at least not in my experience. :) I have found that
                > while breaking changes don't happen often, they *do* happen. Add to
                > this the possibility of different types of API consumers that start
                > off implementing your APIs the same way, but slowly (or rapidly!)
                > diverge over time. In some cases new resources (and thus new URIs)
                > will suffice, but in other cases what we are doing is very
                > specifically *evolving* the resource representation to accommodate
                > new requirements.
                >

                Then design for graceful degradation (or progressive enhancement) using
                client-side feature detection. Just saying there's no need to swing
                the conneg hammer to turn this particular screw.

                -Eric


              • Eric J. Bowman
                ... From hypertext. NOT from knowledge of resource type coupled via custom media type (vnd.order*). It seems like you re asking how to inform the client that
                Message 7 of 13 , Jan 8, 2013
                • 0 Attachment
                  Jørn Wildt wrote:
                  >
                  > My question is though - from where does the client get the
                  > information it needs to extract, say, the order sum, delivery
                  > address, order lines quantity and so on from the generic payload?
                  >

                  From hypertext. NOT from knowledge of resource type coupled via custom
                  media type (vnd.order*). It seems like you're asking how to inform the
                  client that this resource type is "order" -- which is simply not
                  relevant to REST, where the only client knowledge required is of the
                  *interface* to the resource, not the *meaning* of the resource.

                  If my order-form <table> has a <th>quantity</th> column, then the
                  quantity of any item ID is the corresponding <td>, i.e. you code the
                  client with the XPATH expression which yields the answer you're looking
                  for, assuming XHTML. If Xforms is used, this XPATH expression is right
                  there in the form control binding, i.e. a self-documenting API.

                  >
                  > Actually, I would argue that a generic media type is more "typed"
                  > than a domain specific media type. Okay, that sounds like rubbish, I
                  > know - but let me explain:
                  >
                  > - as I stated above, a domain specific media type lets you derived
                  > useful information from a resource without making any assumptions
                  > about its underlying type.
                  >

                  I might agree with that, if generic media types didn't have
                  extensibility mechanisms like, oh I dunno, link relations... AFAIC,
                  domain-specific media types _are_ assumptions about the underlying
                  type, i.e. an "order" is too unique a snowflake to express generically;
                  what other conclusion *can* be drawn about how vnd.order* types are
                  used in practice?

                  >
                  > - whereas a generic media type forces the client to magically assume
                  > the resource has a specific type with specific properties you can
                  > extract from the generic payload.
                  >

                  OK, this is where these discussions always lose me. A browser needs to
                  know *nothing* about resource type, to allow a user to place an order
                  from, like, a bazillion different websites. In REST, the client just
                  needs to know how to manipulate generic hypertext controls. What is it
                  about order processing that makes folks think the client needs to know
                  that it's processing an order?

                  -Eric

                  Now playing, ***** stars for sure:
                  http://archive.org/details/gd1970-11-06.aud.evans.3338.sbefail.shnf
                • Jørn Wildt
                  ... This is my mistake, using the term client wrongly, sorry. According to the dissertation, a client is the library that connects to the web - and the thing
                  Message 8 of 13 , Jan 8, 2013
                  • 0 Attachment
                    > the client just
                    > needs to know how to manipulate generic hypertext controls.
                    > What is it
                    > about order processing that makes folks think the client needs to know
                    > that it's processing an order?

                    This is my mistake, using the term "client" wrongly, sorry. According to the dissertation, a client is the library that connects to the web - and the thing driving the client is the user agent.

                    And that sort of explains it all ... yes, the client "just needs to know how to manipulate generic hypertext controls.". Let me rephrase my question:

                    > > from where does the ***user agent*** get the
                    > > information it needs to extract, say, the order sum, delivery
                    > > address, order lines quantity and so on from the generic payload?

                    But now we are are out of REST country. This is more about application specific details. REST is concerned with the interaction between the client and the server - it does not provide any guidance on how to implement the user agent.

                    Thanks for your feedback - I had actually prepared two long e-mails before I got to this point, so you certainly got me thinking (as has happened before when reading your replies :-)

                    /Jørn

                  • Keith Hassen
                    First of all, thanks for the replies and perspective on REST. Backing up to the original question it seems like your particular take on it is that there s no
                    Message 9 of 13 , Jan 8, 2013
                    • 0 Attachment
                      First of all, thanks for the replies and perspective on REST.

                      Backing up to the original question it seems like your particular take on it is that there's no need to version URIs or the resource representations provided that a cautious approach is taken to resource evolution.

                      To be honest I'm still not sure how this would be handled if two clients diverge in their understanding of the same resource.  Perhaps that divergence leads us to different concepts and thus different resources and I've just been thinking about the problem incorrectly. :)

                      Back to your most recent response...

                      This seems to be a recommended practice that I've encountered in
                      reading about RESTful implementations.


                      Perfectly good HTTP API practice; REST, not so much.  The point of
                      media types is to provide loose coupling based on shared understanding
                      of how the representation is to be decoded.  

                      I think I'm actually talking about loose coupling, but this area seems a little fuzzy.  Comprehensive coverage of media type seems to be missing from Fielding's dissertation.  The media type I specified was definitely too specific (vnd.example.com might be a better choice rather than vnd.example.com.order, the latter effectively binding the media type to the representation and starts smelling like RPC modelling rather than the loose coupling promoted by the RESTful style).

                      So how tight should this coupling be?  And what about versioning?  I'm tempted to say that if versioning is required, do so in the URi rather than the media type.  The media type seems to be more of an assertion/expectation regarding application context rather than a specification of the resource.

                      It's amazing (or maybe not at all amazing) how divided this subject appears to be on the web.  This: http://www.informit.com/articles/article.aspx?p=1566460 is a pretty typical example.

                      Thanks again for the feedback.

                      K


                      On 2013-01-08, at 12:57 AM, Eric J. Bowman wrote:

                      Keith Hassen wrote:

                      This seems to be a recommended practice that I've encountered in
                      reading about RESTful implementations.


                      Perfectly good HTTP API practice; REST, not so much.  The point of
                      media types is to provide loose coupling based on shared understanding
                      of how the representation is to be decoded.  Not tight coupling based
                      on interpreting the content of the representation.  I've never seen an
                      order API that couldn't be represented as HTML; despite any number of
                      variations on this theme (or versions within), the media type doesn't
                      vary between more order APIs on the Web than I can count.

                      REST has no notion of resource "type" let alone of exposing same on the
                      wire, so I've never understood why this solution is so prevalent in REST
                      discussions.  Just media types, which are agnostic as to what "type" of
                      resource is being represented (with rare exceptions as parameters).


                      Anything else is up to the user-agent to work out.  This is actually
                      easier for m2m than h2m; a v1 m2m client should already ignore any
                      hypertext it doesn't understand, rolling out v2 can then re-use any
                      non-deprecated bits of the API already present plus the new stuff,
                      and ignore the deprecated stuff.  Can't it?

                      Not always, at least not in my experience. :)  I have found that
                      while breaking changes don't happen often, they *do* happen.  Add to
                      this the possibility of different types of API consumers that start
                      off implementing your APIs the same way, but slowly (or rapidly!)
                      diverge over time.  In some cases new resources (and thus new URIs)
                      will suffice, but in other cases what we are doing is very
                      specifically *evolving* the resource representation to accommodate
                      new requirements.


                      Then design for graceful degradation (or progressive enhancement) using
                      client-side feature detection.  Just saying there's no need to swing
                      the conneg hammer to turn this particular screw.

                      -Eric

                    • Alexander Johannesen
                      Hiya, ... I think there needs to be made some distinctions between a shared understanding of models and a shared understanding of a resource in that model.
                      Message 10 of 13 , Jan 8, 2013
                      • 0 Attachment
                        Hiya,

                        To be honest I'm still not sure how this would be handled if two clients 
                        > diverge in their understanding of the same resource.

                        I think there needs to be made some distinctions between a shared understanding of models and a shared understanding of a resource in that model. Very often the model stays the same, and so the entities of that models shouldn't change, or at best, provide a framework for dealing with small changes (like backwards compatibility of models).

                        What many confuse as an API change in terms of REST is really a model change, not a change to the language itself, which is REST. Even if the internal representation of a resource changes, its place in the model most often does not, and neither does the interface. True REST (TM) is representational through hyperlinks, and applications should be guided through the model rather than having knowledge of it, at least in an ideal world (but people tend to think the overhead is too great for the world of computing to deal with). There's no point in changing the interface nor the model if only representation changes. That is probably better dealt with through content negotiation, or, at worst, inside the representation level itself.

                        What's being stressed here is that the separation of interface, model and internal representation most often do not require versioning, at least not on the model and interface level. So;

                           /user/johnson
                           /invoice/1023
                           /process/345/participants

                        These are URIs that probably don't change with "versions". So why version them at this level? The model is probably fine, only semantics and representations change, so why not deal with it at that level instead?

                        Hope that makes sense. :) If not, gives us some examples of a change from one version to the next, and let's talk about various ways to deal with the changes in question.


                        Regards,

                        Alex








                        On Wed, Jan 9, 2013 at 4:25 PM, Keith Hassen <keith.hassen@...> wrote:
                         

                        First of all, thanks for the replies and perspective on REST.

                        Backing up to the original question it seems like your particular take on it is that there's no need to version URIs or the resource representations provided that a cautious approach is taken to resource evolution.

                        To be honest I'm still not sure how this would be handled if two clients diverge in their understanding of the same resource.  Perhaps that divergence leads us to different concepts and thus different resources and I've just been thinking about the problem incorrectly. :)

                        Back to your most recent response...

                        This seems to be a recommended practice that I've encountered in
                        reading about RESTful implementations.


                        Perfectly good HTTP API practice; REST, not so much.  The point of
                        media types is to provide loose coupling based on shared understanding
                        of how the representation is to be decoded.  

                        I think I'm actually talking about loose coupling, but this area seems a little fuzzy.  Comprehensive coverage of media type seems to be missing from Fielding's dissertation.  The media type I specified was definitely too specific (vnd.example.com might be a better choice rather than vnd.example.com.order, the latter effectively binding the media type to the representation and starts smelling like RPC modelling rather than the loose coupling promoted by the RESTful style).

                        So how tight should this coupling be?  And what about versioning?  I'm tempted to say that if versioning is required, do so in the URi rather than the media type.  The media type seems to be more of an assertion/expectation regarding application context rather than a specification of the resource.

                        It's amazing (or maybe not at all amazing) how divided this subject appears to be on the web.  This: http://www.informit.com/articles/article.aspx?p=1566460 is a pretty typical example.

                        Thanks again for the feedback.

                        K


                        On 2013-01-08, at 12:57 AM, Eric J. Bowman wrote:

                        Keith Hassen wrote:

                        This seems to be a recommended practice that I've encountered in
                        reading about RESTful implementations.


                        Perfectly good HTTP API practice; REST, not so much.  The point of
                        media types is to provide loose coupling based on shared understanding
                        of how the representation is to be decoded.  Not tight coupling based
                        on interpreting the content of the representation.  I've never seen an
                        order API that couldn't be represented as HTML; despite any number of
                        variations on this theme (or versions within), the media type doesn't
                        vary between more order APIs on the Web than I can count.

                        REST has no notion of resource "type" let alone of exposing same on the
                        wire, so I've never understood why this solution is so prevalent in REST
                        discussions.  Just media types, which are agnostic as to what "type" of
                        resource is being represented (with rare exceptions as parameters).


                        Anything else is up to the user-agent to work out.  This is actually
                        easier for m2m than h2m; a v1 m2m client should already ignore any
                        hypertext it doesn't understand, rolling out v2 can then re-use any
                        non-deprecated bits of the API already present plus the new stuff,
                        and ignore the deprecated stuff.  Can't it?

                        Not always, at least not in my experience. :)  I have found that
                        while breaking changes don't happen often, they *do* happen.  Add to
                        this the possibility of different types of API consumers that start
                        off implementing your APIs the same way, but slowly (or rapidly!)
                        diverge over time.  In some cases new resources (and thus new URIs)
                        will suffice, but in other cases what we are doing is very
                        specifically *evolving* the resource representation to accommodate
                        new requirements.


                        Then design for graceful degradation (or progressive enhancement) using
                        client-side feature detection.  Just saying there's no need to swing
                        the conneg hammer to turn this particular screw.

                        -Eric




                        --
                         Project Wrangler, SOA, Information Alchemist, UX, RESTafarian, Topic Maps
                        --- http://shelter.nu/blog/ ----------------------------------------------
                        ------------------ http://www.google.com/profiles/alexander.johannesen ---
                      • Jørn Wildt
                        If you work with generic media types like plain XML, JSON and(X)HTML (and others) then there is absolutely no reason to version those through the content-type
                        Message 11 of 13 , Jan 8, 2013
                        • 0 Attachment
                          If you work with generic media types like plain XML, JSON and(X)HTML (and others) then there is absolutely no reason to version those through the content-type and content negotiation. I mean, when did the processing rules for XML and JSON last change? Oh, well, the rules for HTML does change - but this is not handled through the media type, but rather through a versioning mechanism inside the payload (the DOCTYPE).

                          "Unfortunately" there is a lot of domain specific media types out there - and since domains changes regularly over time, well, you start thinking that versioning must be done through the media type. And this is where things start to break down. If you avoid domain specific media types (like vnd.order+xml and so on), then you can avoid versioning through the media type.

                          But, of course, your application still evolves over time. Then what?

                          Try these guidelines (and check also Nottingham's blog http://www.mnot.net/blog/2011/10/25/web_api_versioning_smackdown):

                          - Do not expose your internal business objects directly on the wire (for instance by JSON serializing them directly). Do wrap your business objects in a (more) stable external format, such that you are free to change the underlying business objects without the public facing format changing too. Keep that transformation in sync with your internal changes.

                          - Don't make breaking changes to your public format.

                          - Add versioning information inside the payload.

                          - If you have to introduce breaking changes then create a new resource for the new version.

                          - Put links to never versions of the resource into the original resource (for instance using the Link header). Never clients can look for these links and move on to the new and improved version.

                          - Introduce new links, in addition to the old ones, where other resources are linking to your resource (if possible), using new link relation names or similar mechanism. Newer clients will know which of the links to follow - older clients will continue with the link that they have always used.

                          - URLs are not identities for your business data - they are identities for various representations of your business data. I mean, api-v1.example.com/person/1234 is obviously not the same resource as api-v2.example.com/person/1234 - but it can certainly represent exactly the same piece of business data.

                          (and, yes, this is quite the opposite of what I argued in my first post in this thread)

                          /Jørn


                        • Keith Hassen
                          Yeah we definitely make the distinction between the internal representation and the representation exposed to clients. The changes I m thinking about are
                          Message 12 of 13 , Jan 9, 2013
                          • 0 Attachment
                            Yeah we definitely make the distinction between the internal representation and the representation exposed to clients.  The changes I'm thinking about are those dictated by consumers, so in my case I'm thinking of a scenario where two consumers start with the same requirements for a representation of a resource (the thing that is returned to the client when issuing a GET on a certain resource), but then diverge over time.

                            I'm actually having a hard time thinking of a *breaking* change for consumers that can't be accommodated by some kind of additive transformation to the original.  In the worst case, you may have data duplication, for example a user might start off being:

                            { name:"John Smith", address:"123 nowhere ave." }

                            but due to changing requirements needs to change to:

                            { name:"John Smith", address:{street_address:"123 nowhere ave.", postal:"12345", phone:"555-5555"}}

                            In which case the new "address" representation could be added to the original representation using a different name:

                            { name:"John Smith", address:"123 nowhere ave.", full_address:{...}}

                            This allows for compatibility between old and new client requirements.


                            On 2013-01-09, at 12:48 AM, Alexander Johannesen wrote:

                            Hiya,

                            To be honest I'm still not sure how this would be handled if two clients 
                            > diverge in their understanding of the same resource.

                            I think there needs to be made some distinctions between a shared understanding of models and a shared understanding of a resource in that model. Very often the model stays the same, and so the entities of that models shouldn't change, or at best, provide a framework for dealing with small changes (like backwards compatibility of models).

                            What many confuse as an API change in terms of REST is really a model change, not a change to the language itself, which is REST. Even if the internal representation of a resource changes, its place in the model most often does not, and neither does the interface. True REST (TM) is representational through hyperlinks, and applications should be guided through the model rather than having knowledge of it, at least in an ideal world (but people tend to think the overhead is too great for the world of computing to deal with). There's no point in changing the interface nor the model if only representation changes. That is probably better dealt with through content negotiation, or, at worst, inside the representation level itself.

                            What's being stressed here is that the separation of interface, model and internal representation most often do not require versioning, at least not on the model and interface level. So;

                               /user/johnson
                               /invoice/1023
                               /process/345/participants

                            These are URIs that probably don't change with "versions". So why version them at this level? The model is probably fine, only semantics and representations change, so why not deal with it at that level instead?

                            Hope that makes sense. :) If not, gives us some examples of a change from one version to the next, and let's talk about various ways to deal with the changes in question.


                            Regards,

                            Alex








                            On Wed, Jan 9, 2013 at 4:25 PM, Keith Hassen <keith.hassen@...> wrote:
                             

                            First of all, thanks for the replies and perspective on REST.

                            Backing up to the original question it seems like your particular take on it is that there's no need to version URIs or the resource representations provided that a cautious approach is taken to resource evolution.

                            To be honest I'm still not sure how this would be handled if two clients diverge in their understanding of the same resource.  Perhaps that divergence leads us to different concepts and thus different resources and I've just been thinking about the problem incorrectly. :)

                            Back to your most recent response...

                            This seems to be a recommended practice that I've encountered in
                            reading about RESTful implementations.


                            Perfectly good HTTP API practice; REST, not so much.  The point of
                            media types is to provide loose coupling based on shared understanding
                            of how the representation is to be decoded.  

                            I think I'm actually talking about loose coupling, but this area seems a little fuzzy.  Comprehensive coverage of media type seems to be missing from Fielding's dissertation.  The media type I specified was definitely too specific (vnd.example.com might be a better choice rather than vnd.example.com.order, the latter effectively binding the media type to the representation and starts smelling like RPC modelling rather than the loose coupling promoted by the RESTful style).

                            So how tight should this coupling be?  And what about versioning?  I'm tempted to say that if versioning is required, do so in the URi rather than the media type.  The media type seems to be more of an assertion/expectation regarding application context rather than a specification of the resource.

                            It's amazing (or maybe not at all amazing) how divided this subject appears to be on the web.  This: http://www.informit.com/articles/article.aspx?p=1566460 is a pretty typical example.

                            Thanks again for the feedback.

                            K


                            On 2013-01-08, at 12:57 AM, Eric J. Bowman wrote:

                            Keith Hassen wrote:

                            This seems to be a recommended practice that I've encountered in
                            reading about RESTful implementations.


                            Perfectly good HTTP API practice; REST, not so much.  The point of
                            media types is to provide loose coupling based on shared understanding
                            of how the representation is to be decoded.  Not tight coupling based
                            on interpreting the content of the representation.  I've never seen an
                            order API that couldn't be represented as HTML; despite any number of
                            variations on this theme (or versions within), the media type doesn't
                            vary between more order APIs on the Web than I can count.

                            REST has no notion of resource "type" let alone of exposing same on the
                            wire, so I've never understood why this solution is so prevalent in REST
                            discussions.  Just media types, which are agnostic as to what "type" of
                            resource is being represented (with rare exceptions as parameters).


                            Anything else is up to the user-agent to work out.  This is actually
                            easier for m2m than h2m; a v1 m2m client should already ignore any
                            hypertext it doesn't understand, rolling out v2 can then re-use any
                            non-deprecated bits of the API already present plus the new stuff,
                            and ignore the deprecated stuff.  Can't it?

                            Not always, at least not in my experience. :)  I have found that
                            while breaking changes don't happen often, they *do* happen.  Add to
                            this the possibility of different types of API consumers that start
                            off implementing your APIs the same way, but slowly (or rapidly!)
                            diverge over time.  In some cases new resources (and thus new URIs)
                            will suffice, but in other cases what we are doing is very
                            specifically *evolving* the resource representation to accommodate
                            new requirements.


                            Then design for graceful degradation (or progressive enhancement) using
                            client-side feature detection.  Just saying there's no need to swing
                            the conneg hammer to turn this particular screw.

                            -Eric





                            --
                             Project Wrangler, SOA, Information Alchemist, UX, RESTafarian, Topic Maps
                            --- http://shelter.nu/blog/ ----------------------------------------------
                            ------------------ http://www.google.com/profiles/alexander.johannesen ---

                          • Keith Hassen
                            Thanks, the link below is interesting. I think the rules you listed below are good ones and generally make sense. Maybe it is *almost* always true that we
                            Message 13 of 13 , Jan 9, 2013
                            • 0 Attachment
                              Thanks, the link below is interesting.  I think the rules you listed below are good ones and generally make sense.  Maybe it is *almost* always true that we can find a way to either a) make the change non-breaking or b) create a new resource.  In the rare cases where it must be done, then specifying a version in the URI might be necessary, but should be limited to very exceptional cases that I'm having a hard time devising. :)

                              K


                              On 2013-01-09, at 1:45 AM, Jørn Wildt wrote:

                              If you work with generic media types like plain XML, JSON and(X)HTML (and others) then there is absolutely no reason to version those through the content-type and content negotiation. I mean, when did the processing rules for XML and JSON last change? Oh, well, the rules for HTML does change - but this is not handled through the media type, but rather through a versioning mechanism inside the payload (the DOCTYPE).

                              "Unfortunately" there is a lot of domain specific media types out there - and since domains changes regularly over time, well, you start thinking that versioning must be done through the media type. And this is where things start to break down. If you avoid domain specific media types (like vnd.order+xml and so on), then you can avoid versioning through the media type.

                              But, of course, your application still evolves over time. Then what?

                              Try these guidelines (and check also Nottingham's blog http://www.mnot.net/blog/2011/10/25/web_api_versioning_smackdown):

                              - Do not expose your internal business objects directly on the wire (for instance by JSON serializing them directly). Do wrap your business objects in a (more) stable external format, such that you are free to change the underlying business objects without the public facing format changing too. Keep that transformation in sync with your internal changes.

                              - Don't make breaking changes to your public format.

                              - Add versioning information inside the payload.

                              - If you have to introduce breaking changes then create a new resource for the new version.

                              - Put links to never versions of the resource into the original resource (for instance using the Link header). Never clients can look for these links and move on to the new and improved version.

                              - Introduce new links, in addition to the old ones, where other resources are linking to your resource (if possible), using new link relation names or similar mechanism. Newer clients will know which of the links to follow - older clients will continue with the link that they have always used.

                              - URLs are not identities for your business data - they are identities for various representations of your business data. I mean, api-v1.example.com/person/1234 is obviously not the same resource as api-v2.example.com/person/1234 - but it can certainly represent exactly the same piece of business data.

                              (and, yes, this is quite the opposite of what I argued in my first post in this thread)

                              /Jørn



                            Your message has been successfully submitted and would be delivered to recipients shortly.