> 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.
On Fri, Aug 10, 2012 at 10:27 AM, Mike Kelly <mikekelly...@gmail.com> wrote:
> 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"
> >> 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]
> > --
> > 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.
> > 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+unsubscribe@googlegroups.com.
> Visit this group at http://groups.google.com/group/api-craft?hl=en.
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 <kswi...@gmail.com> wrote:
> 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.
>> 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.
> --
> 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.
> Visit this group at http://groups.google.com/group/api-craft?hl=en.
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".
On Fri, Aug 10, 2012 at 10:44 AM, mca <m...@amundsen.com> wrote:
> 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].
>> Steve, do you think that a profile is a form of "type specification"
>> that Roy is arguing against in the above quote?
>> Cheers,
>> M
>> On Fri, Aug 10, 2012 at 3:32 PM, Steve Klabnik <st...@steveklabnik.com>
>> wrote:
>> > I'm not.
>> > I do provide a media type and/or profile, though.
>> --
>> 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.
>> 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+unsubscribe@googlegroups.com.
> Visit this group at http://groups.google.com/group/api-craft?hl=en.
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.
On Fri, Aug 10, 2012 at 11:47 AM, Daniel Roop <dan...@danielroop.com> wrote:
> 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".
> On Fri, Aug 10, 2012 at 10:44 AM, mca <m...@amundsen.com> wrote:
>> 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].
>>> Steve, do you think that a profile is a form of "type specification"
>>> that Roy is arguing against in the above quote?
>>> Cheers,
>>> M
>>> On Fri, Aug 10, 2012 at 3:32 PM, Steve Klabnik <st...@steveklabnik.com>
>>> wrote:
>>> > I'm not.
>>> > I do provide a media type and/or profile, though.
>>> --
>>> 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.
>>> 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+unsubscribe@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+unsubscribe@googlegroups.com.
> Visit this group at http://groups.google.com/group/api-craft?hl=en.
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.
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.
On Thu, Aug 9, 2012 at 1:49 PM, Greg Brail <g...@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 <kswi...@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 <cappela...@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
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
> On Fri, Aug 10, 2012 at 11:06 AM, Kevin Swiber <kswi...@gmail.com> wrote:
> 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.
> 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.
On Fri, Aug 10, 2012 at 10:02 AM, Kevin Swiber <kswi...@gmail.com> wrote:
> One way to accomplish this is by building version selection into your
> messaging.
> 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.
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.
On Fri, Aug 10, 2012 at 9:43 AM, Peter Williams <pe...@barelyenough.org> wrote:
> On Fri, Aug 10, 2012 at 10:02 AM, Kevin Swiber <kswi...@gmail.com> wrote:
>> One way to accomplish this is by building version selection into your
>> messaging.
>> 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
> --
> 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.
> Visit this group at http://groups.google.com/group/api-craft?hl=en.
-- --
--
Justin Kruger
Social Media Software Engineer -
San Francisco, CA
On Fri, Aug 10, 2012 at 10:31 AM, Pat Cappelaere <cappela...@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.
> On Fri, Aug 10, 2012 at 10:02 AM, Kevin Swiber <kswi...@gmail.com> wrote:
> > One way to accomplish this is by building version selection into your
> > messaging.
> > 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.
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 <cappela...@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.
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.
On Fri, Aug 10, 2012 at 12:02 PM, Kevin Swiber <kswi...@gmail.com> wrote:
> 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.
> 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 <g...@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 <kswi...@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 <cappela...@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
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.
On Aug 10, 2012, at 1:25 PM, Kevin Swiber <kswi...@gmail.com> wrote:
> 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.
> On Fri, Aug 10, 2012 at 12:02 PM, Kevin Swiber <kswi...@gmail.com> wrote:
> 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.
> 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 <g...@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 <kswi...@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 <cappela...@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.
On Fri, Aug 10, 2012 at 11:23 AM, Pat Cappelaere <cappela...@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?
> On Fri, Aug 10, 2012 at 11:23 AM, Pat Cappelaere <cappela...@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.
On Fri, Aug 10, 2012 at 11:22 AM, Kevin Swiber <kswi...@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.
> 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.
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 <cappela...@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.
> --
> 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.
> Visit this group at http://groups.google.com/group/api-craft?hl=en.
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.
On Fri, Aug 10, 2012 at 1:09 PM, Pat Cappelaere <cappela...@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.
On Aug 10, 2012, at 3:50 PM, Peter Williams <pe...@barelyenough.org> wrote:
> On Fri, Aug 10, 2012 at 1:09 PM, Pat Cappelaere <cappela...@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.
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 ?
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.
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 #.
On Aug 10, 2012, at 1:31 PM, 13protons <a...@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.
On 10 Aug 2012, at 18:23, Pat Cappelaere <cappela...@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: