kevinswiber / siren

Structured Interface for Representing Entities, super-rad hypermedia
MIT License
1.29k stars 71 forks source link

What's different/better/worse than other JSON hypermedia media types? #15

Closed emmanuel closed 10 years ago

emmanuel commented 10 years ago

Some sort of comparison with other well-known JSON media types would really help me evaluate which of these I should use for a given service.

HAL+JSON (Hypertext Application Language) is the oldest of these of which I'm aware (originally published in mid-2011). Its author Mike Kelly has also produced a corresponding XML media type.

Collection+JSON is detailed in the book Building Hypermedia APIs with HTML5 and Node, by Mike Amundsen. I don't think there is a corresponding XML media type.

Finally, Percolator.js for Node.js has a sort-of/kind-of media type in its default production of JSON responses.

What's better/worse/different about Siren than any of the above?

kevinswiber commented 10 years ago

Hey @emmanuel! This is a frequently asked question. Pinging @mamund and @mikekelly to see if they know of any trusted, non-biased, existing comparison.

The biggest differentiator of Siren is Actions. I believe the closest Collection+JSON gets with this is write templates. HAL has no concept of inline input metadata for submitting requests, though there was something called HALO that I think may have supported that at one time. (I'm sure the authors will correct me if I'm wrong. :)

Siren also has a concept of "class." The class attribute may contain multiple descriptors of the current representation. I've avoided calling these "type descriptors." They act more like "mixin descriptors" (i.e., if an entity is of a certain class, it may have properties, actions, sub-entities, or links associated with it). When layering a UI on top of Siren, I've also used the class attribute to act as a view router (e.g., When a representation comes back with an "error" class, route to the error view or when a representation contains a "home" class, route to the home view... or some combination... When a representation has both the "home" and "error" classes, display the error alongside the home view.) This could also be done in an M2M scenario.

For HAL, that "class" type information would be contained in the link relation documentation. I think for Cj, that info would have to be an attribute inside the data array or in the link relation documentation. Again, I'll let the authors chime in if this is incorrect.

mamund commented 10 years ago

adding my voice here:

i designed Cj to take advantage of the CRUD model PLUS the ability to describe the details of queries (including possible values) and a "write" operation (for POST and PUT items in the collection). that means Cj is basically ATOM + Queries and Templates.

if your model does not lend itself to collections well, Cj is going to be an uncomfortable fit. i've implemented quite a number of problem domains w/ it, but i eventually run into the limits of item-based CRUD+Query after a while.

just sayin' ;)

On Thu, Aug 29, 2013 at 3:45 PM, Kevin Swiber notifications@github.comwrote:

Hey @emmanuel https://github.com/emmanuel! This is a frequently asked question. Pinging @mamund https://github.com/mamund and @mikekellyhttps://github.com/mikekellyto see if they know of any trusted, non-biased, existing comparison.

The biggest differentiator of Siren is Actionshttps://github.com/kevinswiber/siren#actions-1. I believe the closest Collection+JSON gets with this is write templates. HAL has no concept of inline input metadata for submitting requests, though there was something called HALO that I think may have supported that at one time. (I'm sure the authors will correct me if I'm wrong. :)

Siren also has a concept of "class." The class attribute may contain multiple descriptors of the current representation. I've avoided calling these "type descriptors." They act more like "mixin descriptors" (i.e., if an entity is of a certain class, it may have properties, actions, sub-entities, or links associated with it). When layering a UI on top of Siren, I've also used the class attribute to act as a view router (e.g., When a representation comes back with an "error" class, route to the error view or when a representation contains a "home" class, route to the home view... or some combination... When a representation has both the "home" and "error" classes, display the error alongside the home view.) This could also be done in an M2M scenario.

For HAL, that "class" type information would be contained in the link relation documentation. I think for Cj, that info would have to be an attribute inside the data array or in the link relation documentation. Again, I'll let the authors chime in if this is incorrect.

— Reply to this email directly or view it on GitHubhttps://github.com/kevinswiber/siren/issues/15#issuecomment-23517991 .

mikekelly commented 10 years ago

HAL is geared towards "m2m" APIs. Its deliberately minimalistic in its design, so as Kevin rightly points out it has no concept of inline forms. It is very focused

mikekelly commented 10 years ago

.. on the use of link relations to describe the possible transitions of an application. It is not difficult to process, in fact you could consume HAL the same way you would any normal JSON and you won't be caught out by any magical rules! HTH!! Thanks for copying me in @kevinswiber

zdne commented 10 years ago

This is very helpful discussion! I was asking Kevin the very same question couple months ago. However it is invaluable to get the point of view of the authors of other formats!

Personally I was not aware of the Percolator format until today. I have asked @cainus, author of Percolator.js, about the motivation behind the Hyper+JSON. You can find his very informative answer here.

Apparently everyone was tackling the problem with a different use-case on mind, but to me Kevin and Gregg had somewhat similar goal in the support of an arbitrary "form / action" for a link while HAL stays as sparse as possible.

ericelliott commented 10 years ago

The one thing that I dislike about HAL is that is is so minimal -- that is intentional, of course, but it mixes the hypermedia metadata in with your actual application data, leaving the client to sort it out. I'm sure that works for a lot of use-cases, but it rubs me wrong. I'm a fan of both Collection+JSON and Siren, where there is clear, consistent separation between the hypermedia elements and your application data, as well as a slightly richer vocabulary for expressing hypermedia concerns.

However, if you don't want to build or use a client / library that knows how to interpret that vocabulary and extract your application data, that is where HAL really shines -- it should just work out of the box. You could easily add it to an existing project without changing much of anything, which would make it very easy to gradually transition an existing system to a more hypermedia-aware API.

emmanuel commented 10 years ago

This is extremely helpful.

Frankly, I'm delighted and humbled to have insight "from the horse's mouth(s)" (er, content-type authors) about the motivations and differences between these formats.

I've been working in a big company for a little bit, I didn't do nearly as much open source related work in the last year as I had in each of the previous 5, and I almost forgot how phenomenal the open source community is.

Thanks everyone!

...closing because I think this question is now satisfactorily answered. Future askers can be directed here for enlightenment.

cainus commented 10 years ago

I'm not sure if anyone else is thinking this too, but wouldn't it be a huge boon to hypermedia APIs if we all got together, determined the lowest-common-denominator for links in json, and came up with a proposal? There are so many formats now, and they do have a lot of similarities and commonalities. I know we disagree on a number of points, but I bet there is enough that we agree on that we could present a unified proposal, one that is still compatible with the formats that we're individually proposing.

ericelliott commented 10 years ago

image

mikekelly commented 10 years ago

:point_up:

cainus commented 10 years ago

Too true :)

But who actually thinks we have competing standards? Writing up some RFCs or even getting IANA approval doesn't mean standardization has been accomplished. There needs to be widespread usage. And none of these frameworks and media-types have achieved that. That makes now a great time to standardize. We've seen how our different media-types actually work in the real world, and what matters and what doesn't, but there's no actual widespread usage (yet).

BTW... I'm just talking about standardizing on a problem that we've all had to solve: links in json, eg.:

We're actually all very close and I don't see any valuable reason whatsoever for the minor dissimilarities. Does anyone else? Are there really competing design goals on those issues? I could certainly sacrifice some of my minor design goals for the bigger goal of inter-operability.

mamund commented 10 years ago

Gregg:

we have a number of designs created here. usage of those designs matters. the design most often used are the design most worthy of adding to the list of RFCs.

every app you build is a vote. every client that requests a server support media type X is a vote. every server that add support for media type X is a vote.

if it turns out none of the current designs are getting enough votes then someone needs to create some new designs. ones closer to that which devs want to use.

its simple, but not clean. its effective, but not efficient. and its what we have ;)

On Sun, Sep 15, 2013 at 6:00 PM, Gregg Caines notifications@github.comwrote:

Too true :)

But who actually thinks we have competing standards? Writing up some RFCs or even getting IANA approval doesn't mean standardization has been accomplished. There needs to be widespread usage. And none of these frameworks and media-types have achieved that. That makes now a great time to standardize. We've seen how our different media-types actually work in the real world, and what matters and what doesn't, but there's no actual widespread usage (yet).

BTW... I'm just talking about standardizing on a problem that we've all had to solve: links in json, eg.:

  • what to name the object
  • if the object should be an array or hash
  • how to denote rels
  • how to denote hrefs

We're actually all very close and I don't see any valuable reason whatsoever for the minor dissimilarities. Does anyone else? Are there really competing design goals on those issues? I could certainly sacrifice some of my minor design goals for the bigger goal of inter-operability.

— Reply to this email directly or view it on GitHubhttps://github.com/kevinswiber/siren/issues/15#issuecomment-24481272 .

cainus commented 10 years ago

Well I'd definitely agree if not for the fact that I'm only talking about the differences that at this point don't appear to matter. If I'm being dense and you've seen a huge impact in actual usage by calling the object "_links" vs "links", please let me know. On the contrary, these types of APIs have been out for years now, and I haven't heard anyone choose one format over another based on that (It seems we're even unanimous on using the word "href" as the property name for the url. That could be a start!).

The worst part (to me at least) is that we're all independently working on many of the exact same problems. These differences are hampering tooling and interop, and the proliferation of hypermedia apis in general.

Anyway... I'll drop it. I honestly hope any (or all) of these formats gains a huge following someday because that'll mean widespread use of hypermedia apis.

mamund commented 10 years ago

gregg:

yep - all the things you mention are an issue. if it turns out there are some minor details you don't like but can live with, then that's proly the media type to start with.

keep in mind that HTTP lets both servers and clients select matching media types at runtime (content negotiation). when you build your app (client or server) you can make representation of the internal object graph a "layer" or black box in your implementation model:

string representation = createOutput("application/hal+json", userObject);

now, future media type choices only need you to update the createOuput and pass the new argument.

this "future-proofs" your work and lowers the risk of embedding a single representation format into all your apps.

On Sun, Sep 15, 2013 at 7:19 PM, Gregg Caines notifications@github.comwrote:

Well I'd definitely agree if not for the fact that I'm only talking about the differences that at this point don't appear to matter. If I'm being dense and you've seen a huge impact in actual usage by calling the object "_links" vs "links", please let me know. On the contrary, these types of APIs have been out for years now, and I haven't heard anyone choose one format over another based on that (It seems we're even unanimous on using the word "href" as the property name for the url. That could be a start!).

The worst part (to me at least) is that we're all independently working on many of the exact same problems. These differences are hampering tooling and interop, and the proliferation of hypermedia apis in general.

Anyway... I'll drop it. I honestly hope any (or all) of these formats gains a huge following someday because that'll mean widespread use of hypermedia apis.

— Reply to this email directly or view it on GitHubhttps://github.com/kevinswiber/siren/issues/15#issuecomment-24482825 .

ericelliott commented 10 years ago

@cainus _links vs links matters because the formats that are using _links largely MUST do something like underscore to prevent collisions with the keys for objects being represented. That's the major problem I see with formats that mix the represented object keys with special keys. If it weren't for that, you could easily change the name of the links collection, and it probably wouldn't matter much.

mikekelly commented 10 years ago

Yes, collisions might happen but the media type could just make "links" with no underscore a reserved property and force implementors to work around it. That would be a valid decision and in practice it would probably only affect a small % of people.

There are bigger distinctions though, e.g. most other media types model links as an array, whereas HAL uses an object and the rels as keys. Link relations are the primary means of identifying a link, so I think HAL's approach makes the best use of JSON to present that - some people worry more about the edge case in which someone may want to represent one link with multiple rels (and don't want to have to represent these as multiple links to the same URI) so they instead model it as an array and establish rules for plucking out the links. fwiw, judging by personal experience, the latter is never actually necessary (is not worth the convolution) and is basically a poor design decision - that's just my opinion but unless someone comes up with hard evidence to the contrary I can't see my opinion on that changing and (although it might seem trivial) I actually think it matters so I wouldn't want to change that about HAL.

But I also think that's ok, there's a whole bunch of libraries available for serving and consuming HAL - and I think there's a bunch for cj and siren too. All the projects seem to get along fine alongside each other, some libraries cover many of them (roar that @mamund mentioned does this).

In the end, if you are concerned about fragmentation - you should pick a horse and evangelise it. I suspect that adoption over the next couple of years will be driven by who makes the most noise (i.e. writing books, blog posts, tweets) telling people how they should be using/doing things.. and, fwiw, that might be a reason not to pick he hal-horse because I barely even have enough spare time to edit the damn thing these days! :disappointed:

I'm tempted to hand it off to someone else, actually. I just need to find someone I can trust not to try and stick anything form-like in it. (joking [kind of]) :laughing:

ericelliott commented 10 years ago

@mikekelly Actually, I think HAL's use of rel as an object key is weird.

1) Because you might want to use the same rel for multiple links, and 2) Because you might want to represent a single link with multiple rels

Either way, you have to do awkward things to make that happen. More awkward, I think, than selecting a link from an array.

mikekelly commented 10 years ago

Yes, we have different opinions - and that's ok..! But I'll bite anyway:

1) this has always been possible with hal+json since properties in the _links object can be either an object or an array, i.e.

{
  "_links": {
     "many-things": [{ ... link ... }, { ... link ... }],
     "one-thing": { ... link .... }
  }
}

2) I already made this point, but it's not really a very strong one because:

a) it's fairly easy to argue most people don't need or want to do this most of the time (it's "advanced") b) anyone wanting to do this can express a multi-rel link in HAL as multiple links with the same target URL - and this can be worked backwards into the same info a multi-rel link would convey fairly easily.

It makes more sense to me to have the easier affordance for the simpler, common use-case; and the more difficult affordance for the more complicated, uncommon use-case.

mikekelly commented 10 years ago

Addressing a single link:

HAL-way:

response._links.thing;

Array-of-multi-rel-links-way:

response.links.filter(function(link) {
  return link.rel.split(' ').indexOf('thing') != -1;
})[0];
kevinswiber commented 10 years ago

I'm going to call bike-shedding on the links issue.

I think we've defined capabilities for both models. Siren supports in-message link representations that correspond with the fields used by Web Linking RFC5988[1]. This also aligns with HTML, which isn't too uncommon for Siren. An earlier design even used space-separated strings to depict arrays. I found this silly and just added a couple of square brackets. To my taste, looking at a couple of brackets is a fair compromise to avoid checking the type of the value at parse time and executing conditional logic. ("Is it an array or a string... or an object... or a...?"). Having a known, reliable object structure for Siren messages has been a benefit to me during implementation time.

HAL is intended to be minimal, and so compromises are made to support that design constraint. IMO, HAL has acted as a good on-ramp for developers wanting to take their existing API and support Web Linking without breaking older clients. It continues to do so successfully.

Siren is intentionally full of features. Some of these features may be more than what some developers need. That's okay. Much of a Siren entity is optional. I'm disinclined to change the design of Links to something that creates incompatibilities with RFC 5988. From my point of view, there's a huge benefit to capitalizing on an existing specification (i.e., Siren itself doesn't have to do much re-specifying).

I've been in a few conversations around convergence of specifications. I don't think we're there yet. In my mind, while there is a lot of overlap between available JSON hypermedia types, they are crafted to be optimized for different use cases. This creates a richness in diversity, and that's something to be celebrated.

[1] http://tools.ietf.org/html/rfc5988

ericelliott commented 10 years ago

I agree. HAL is good for its use-case, but I don't see the HAL model as a general solution for everything. Likewise, converting an existing API to Siren or Collection+JSON might be a slightly more difficult task than converting it to HAL.

I don't see a strong case for convergence between HAL and Siren or Collection+JSON, but maybe there are enough similarities in Collection+JSON and Siren linking to use the same link standard?

mikekelly commented 10 years ago

for the record, it doesn't create incompatibilities with the web linking spec: it just makes achieving one small part of the spec (namely the multi-rel capability of the Link header serialisation) more cumbersome.

It's also worth noting that the wording of RFC5988 actually implies that "a link" is a singular relation between two IRIs:

3.  Links

   In this specification, a link is a typed connection between two
   resources that are identified by Internationalised Resource
   Identifiers (IRIs) [RFC3987], and is comprised of:

   o  A context IRI,

   o  a link relation type (Section 4),

   o  a target IRI
mikekelly commented 10 years ago

Worrying about underscore prefixes is bike-shedding. This issue of using an array or an object, isn't. It's fairly fundamental to a hypermedia type - hence:

Addressing a single link:

HAL-way:

response._links.thing;

Array-of-multi-rel-links-way:

response.links.filter(function(link) {
 return link.rel.split(' ').indexOf('thing') != -1;
})[0];
mikekelly commented 10 years ago

to be fair Siren is a bit less complicated:

response.links.filter(function(link) {
 return link.rels.indexOf('thing') != -1;
})[0];

.....

:trollface:

kevinswiber commented 10 years ago

@cainus @dilvie I'm still unclear as to what the benefit is of converging on a subset of a media type. When writing handlers for multiple media types, it seems to me that link parsing isn't as big of a deal as handling the different semantics available between types. If link semantics match, but everything else is fundamentally different, what is the gain, exactly? I feel like I'm missing something. Help me out.

@mikekelly Ah, I must be taking the multiple-rel hint from HTML then. Thanks for the correction.

kevinswiber commented 10 years ago

@mikekelly Re: finding links

Most developers won't even know this implementation detail and will just use a library that handles it automagically. I don't see it as being a big deal. Parsing any of these formats is relatively easy. Once specs are stable, this is often a "set it and forget it" situation.

It's more important to focus on enablement. What does this media type enable?

I've been speaking with folks interested in Siren because it supports dynamic workflows. I don't know any other JSON-based hypermedia type better at that use case.

ericelliott commented 10 years ago

@mikekelly It's pretty trivial to abstract the link retrieval differences away in clients. The first thing I did when I started using Collection+JSON and Siren is write a model for hypermedia responses that lets you do:

var richResponse = hyper(response);
richResponse.links.get('someRel');
mikekelly commented 10 years ago

@kevinswiber I don't really know what a "dynamic workflow" is, can you give an example?

mikekelly commented 10 years ago

I'm suspicious about this "its very simple if you just use this library" angle.. RESTful HTTP has overcome SOAP in the mainstream not through greater enablement but by requiring very little tooling and therefore allowing people to build small components that are 'close to the wire'.

kevinswiber commented 10 years ago

@mikekelly

Sure. We'll talk M2M with a UI close to the client. (Not exactly UI over API.)

A retail customer starts a transaction on their mobile device after filling a digital shopping cart. If the customer does not have a loyalty number, the server should offer a response to request one be provided prior to continuing the transaction. At this point, the transaction is locked and may not be cancelled. It will auto-cancel after a set timeout. If the customer has a loyalty number assigned, the server should offer a response that allows confirmation of shopping cart items as well as the option to edit the shipping address, which is only a detail of the transaction entity itself. At this point, there should be an option to cancel the transaction, as well.

Siren can model all of this in-message with a "follow-your-nose" approach. There's no need to predefine a list of statuses or how that might alter the capabilities of a resource behind the scenes. The available capabilities are expressed inline, and developers can code a state machine consumer that depends on these available transitions. There is less trial and error. Siren's design supports this complexity very well.

While I have used Siren for CRUD, I see more interest in it for its ability to communicate dynamic state transitions. Perhaps you know of a good way to do this in HAL, but it's not obvious to me without creating compromises I wouldn't want to make in my resource design.

kevinswiber commented 10 years ago

@mikekelly The point is the difference between parsing either style is negligible. In my experience, most people prefer to use a library unless they're doing some complex proxying of a particular API. In this case, they want to know the REST API message design, because they are often directly manipulating it. The majority of developers, in my experience, want the value behind the API and don't care how it looks over the network, as long as it doesn't kill their performance requirements. API providers want APIs that support extending reach, providing value, and making money. The structure of a links collection has very little to do with that. The capabilities of the message design are more important than the structural implementation. We all agree that having links is a great capability. That's why I called bike-shedding. ;)

ericelliott commented 10 years ago

@mikekelly You'd have a stronger point if this was hard...

response.links.filter(function(link) {
 return link.rels.indexOf('thing') != -1;
})[0];

But I also think that hypermedia has yet to explode (everybody's talking the talk, but relatively few are walking the walk) primarily because we don't have the killer app, yet -- a client side library or implementation that really fulfills the decoupling promise of hypermedia APIs. Yeah, the generic admin consoles are pretty cool, but no library has really gained critical mass here.

In other words, I believe that it's impossible to realize the true hypermedia API potential without a robust client side library solution -- even if you're using HAL. It's not that you need a library to interact with the API -- but a good library can make it a lot easier to establish disciplined decoupling (and gain all the advantages that go along with it) on the client.

@kevinswiber Makes a compelling case about communicating state transitions that would work wonderfully with a well designed client library. Percolator was inspired by something similar, IIRC.

mikekelly commented 10 years ago

@kevinswiber I don't think the difference would manifest itself in how the resources were designed, or even the transitions, I think the biggest difference is merely in when/where you offer up stuff-to-couple-a-coded-client-against.

There's no need to predefine a list of statuses or how that might alter the capabilities of a resource behind the scenes. The available capabilities are expressed inline, and developers can code a state machine consumer that depends on these available transitions.

So instead of statuses, it's 'capabilities'? But as far as the coded client is concerned those capabilities were similarly predefined, right? I think it would help to look at this in the concrete (i.e. examples of the kids of messages you're thinking about).

mikekelly commented 10 years ago

API providers want APIs that support extending reach

Exactly. The less you require of your clients to understand what's actually going on in your API, the greater your reach. Complex mechanical affordances do not magically solve this problem, SOAP being an excellent case in point.

mikekelly commented 10 years ago

This is why a lot of the affordances in HAL are targeted at humans, not machines.

kevinswiber commented 10 years ago

I think what you're missing is that this isn't unnecessary technical complexity. This is technology supporting necessary domain complexity.

I feel a little déjà vu. Maybe we should once again agree to disagree. ;)

Sent from my iPhone

On Sep 16, 2013, at 6:18 PM, Mike Kelly notifications@github.com wrote:

API providers want APIs that support extending reach

Exactly. The less you require of your clients to understand what's actually going on in your API, the greater your reach. Complex mechanical affordances do not magically solve this problem, SOAP being an excellent case in point.

— Reply to this email directly or view it on GitHubhttps://github.com/kevinswiber/siren/issues/15#issuecomment-24549525 .

cainus commented 10 years ago

Alright... clearly I'm an asshat, and clearly we should agree to disagree. I still don't really regret bringing this up though, because the ensuing discussion was awesome. Thanks for indulging me.

I'm going to proceed to argue with everybody now. :)

I'm suspicious about this "its very simple if you just use this library" angle.. RESTful HTTP has overcome SOAP in the mainstream not through greater enablement but by requiring very little tooling and therefore allowing people to build small components that are 'close to the wire'.

This is actually my opinion on libraries-solving-format-complexities as well. The HAL way (which I think is the same as the Percolator way in this regard), doesn't really require any additional tooling than what people are already using. It's only after you write client libraries for every possible platform that these two begin to compare:

response.links.filter(function(link) {
 return link.rels.indexOf('thing') != -1;
})[0];

vs.

response.links.thing;

I sell my format by telling people that it's just json with links, so they can just use the same json parser and they don't have to construct their own links in the client anymore (yay!). I think when it's that easy, we can start sucking people into going further and using Siren-style actions, or Percolator-style non-GET links (what @mikekelly would call "forms" I think). I think usability and even marketing are somewhat important.

With that said: the one thing I hate about the simpler format is when thing needs to be an array (say you're modelling a family tree and the rel is "child" -- of course a person could have multiple children), the simpler way becomes not-so-simple, but then again I think that's not really accidental complexity. ( If I have multiple rels for the same link however, I just make multiple links -- or I would anyway, if I'd ever had that problem).

@kevinswiber @dilvie : Percolator is meant for follow-your-nose APIs as well, and so I'm starting to get into writing a client (for javascript at least). I'd love to hear about anything you've already accomplished in that area, or plan to. There might be some ideas we can steal from each other. I'm thinking specifically about the follow-your-nose/HATEOAS style of capability discovery and how to represent that in a client. I'm also thinking that bookmarking/link-caching might be a useful feature. Are you guys thinking along the same lines? Have any other interesting ideas? It's a bit of a wild frontier. I'm only just starting to write web-apps that follow-their-noses, and many are still hard-coding a number of links for the sake of simplicity. Most of the value in Percolator so far has been the ease of human consumption.

ericelliott commented 10 years ago

I really believe that hard coding links is missing the point. I'm combining hypermedia APIs and feature toggle systems, using the hypermedia's inherent feature discovery capabilities.

kevinswiber commented 10 years ago

I think I found the gap in communication.

I don't believe any of these formats is absolutely complex. I've had more problems with EDI flat files. We seem to be talking about relative complexity. Yes, Siren is more complex a format than HAL, but not by much. I don't think this is developers' greatest deterrent from hypermedia.

Developers handle much greater complexity than HAL or Siren or Percolator every single day. Business processes are deeply complex. Hypermedia format battles pour energy into a non-existent problem, IMO.

Sent from my iPhone

On Sep 17, 2013, at 8:43 AM, Gregg Caines notifications@github.com wrote:

Alright... clearly I'm an asshat, and clearly we should agree to disagree. I still don't really regret bringing this up though, because the ensuing discussion was awesome. Thanks for indulging me.

I'm going to proceed to argue with everybody now. :)

I'm suspicious about this "its very simple if you just use this library" angle.. RESTful HTTP has overcome SOAP in the mainstream not through greater enablement but by requiring very little tooling and therefore allowing people to build small components that are 'close to the wire'.

This is actually my opinion on libraries-solving-format-complexities as well. The HAL way (which I think is the same as the Percolator way in this regard), doesn't really require any additional tooling than what people are already using. It's only after you write client libraries for every possible platform that these two being to compare:

response.links.filter(function(link) { return link.rels.indexOf('thing') != -1;})[0];

vs.

response.links.thing;

I sell my format by telling people that it's just json with links, so they can just use the same json parser and they don't have to construct their own links in the client anymore (yay!). I think when it's that easy, we can start sucking people into going further and using Siren-style actions, or Percolator-style non-GET links (what @mikekellyhttps://github.com/mikekellywould call "forms" I think). I think usability and even marketing are somewhat important.

With that said: the one thing I hate about the simpler format is when thingneeds to be an array (say you're modelling a family tree and the rel is "child" -- of course a person could have multiple children), the simpler way becomes not-so-simple, but then again I think that's not really accidental complexity. ( If I have multiple rels for the same link however, I just make multiple links -- or I would anyway, if I'd ever had that problem).

@kevinswiber https://github.com/kevinswiber @dilviehttps://github.com/dilvie: Percolator is meant for follow-your-nose APIs as well, and so I'm starting to get into writing a client (for javascript at least). I'd love to hear about anything you've already accomplished in that area, or plan to. There might be some ideas we can steal from each other. I'm thinking specifically about the follow-your-nose/HATEOAS style of capability discovery and how to represent that in a client. I'm also thinking that bookmarking/link-caching might be a useful feature. Are you guys thinking along the same lines? Have any other interesting ideas? It's a bit of a wild frontier. I'm only just starting to write web-apps that follow-their-noses, and many are still hard-coding a number of links for the sake of simplicity. Most of the value in Percolator so far has been the ease of human consumption.

— Reply to this email directly or view it on GitHubhttps://github.com/kevinswiber/siren/issues/15#issuecomment-24584803 .

cainus commented 10 years ago

@kevinswiber : yeah... I get your point. We are talking about details compared to the larger problem. In many ways, that was my original point. But I can see that everyone (including me) also thinks the details matter enough to keep the differences.

I also agree; If I want to write a client that can consume HAL, Siren and Percolator's format, it's pretty trivial to just sniff the content-type and change link traversing logic accordingly.

@dilvie Great idea... You don't have to ship a bunch of feature toggles to the client-side that way. The client can just learn about its capabilities along the way. I've been doing something similar, but with different user roles as the main driver of what capabilities the client has (and links -- or the lack of links -- being the way those capabilities are indicated).

mikekelly commented 10 years ago

Developers handle much greater complexity than HAL or Siren or Percolator every single day. Business processes are deeply complex.

Yes, but that's not an excuse or a valid reason for adding yet more complexity on top, and this is why I believe media types should be doing just enough to be of practical value but other than that making sure they stay out of the way.

Hypermedia format battles pour energy into a non-existent problem, IMO.

I think if people want to understand the reasoning behind the difference in designs then it is reasonable to spend some energy trying to explain ourselves. I guess you agree with that.. you're still here after all! :smile:

ericelliott commented 10 years ago

Yes, but that's not an excuse or a valid reason for adding yet more complexity on top, and this is why I believe media types should be doing just enough to be of practical value but other than that making sure they stay out of the way.

I think we're all agreed on this point. We just disagree on how much is "just enough". And that's OK. =)

ericelliott commented 10 years ago

You don't have to ship a bunch of feature toggles to the client-side that way. The client can just learn about its capabilities along the way. I've been doing something similar, but with different user roles as the main driver of what capabilities the client has (and links -- or the lack of links -- being the way those capabilities are indicated).

Yep, but a lack of a link can't be a feature toggle if the client just hard-codes the link anyway. The user will get broken UI. =P

cainus commented 10 years ago

@dilvie : Yep... that was my point. Definitely trying to murder that anti-pattern.

kevinswiber commented 10 years ago

@mikekelly

I think if people want to understand the reasoning behind the difference in designs then it is reasonable to spend some energy trying to explain ourselves. I guess you agree with that.. you're still here after all!

Yes, I'm still here, but let's not pretend this conversation is to help the general population. We're essentially at a standstill due to a lack of compromise. I think HAL serves its purpose. You think Siren has unnecessary complexity. This has been our position for over a year now, and few outside those who have commented on this thread actually care.

I'd rather shift to focus on implementing use cases, though that is significantly more time-consuming. Interested in giving the above-mentioned use case a shot? (Open to any takers.) I'd love to see how this manifests in APIs of various media types.

apsoto commented 10 years ago

If anyone wants to check out a public Siren API in production. Still in it's infancy. Does have actual customer usage, albeit in prototype phase at the moment, but real customer apps are coming. I don't have any feedback from customers yet, but no one's complained either.

https://api.wurl.com/api?format=json

You'll need to register to create an access token to get beyond the root response though:

http://developers.wurl.com/pages/guides/getting-started

On Tue, Sep 17, 2013 at 11:46 AM, Kevin Swiber notifications@github.comwrote:

@mikekelly https://github.com/mikekelly

I think if people want to understand the reasoning behind the difference in designs then it is reasonable to spend some energy trying to explain ourselves. I guess you agree with that.. you're still here after all!

Yes, I'm still here, but let's not pretend this conversation is to help the general population. We're essentially at a standstill due to a lack of compromise. I think HAL serves its purpose. You think Siren has unnecessary complexity. This has been our position for over a year now, and few outside those who have commented on this thread actually care.

I'd rather shift to focus on implementing use cases, though that is significantly more time-consuming. Interested in giving the above-mentioned use case a shot? (Open to any takers.) I'd love to see how this manifests in APIs of various media types.

— Reply to this email directly or view it on GitHubhttps://github.com/kevinswiber/siren/issues/15#issuecomment-24612705 .

darrelmiller commented 10 years ago

If you're not using application/json or application/xml as a media type, I think you're awesome. That's all I have to say.

darrelmiller commented 10 years ago

Actually I lied. I do have more to say. The fact that you guys are debating this stuff means you get the significance of media types in a web architecture. There are a bazillion other devs who do not. If their perception of us is that we spend our days arguing about whether it should be "links" or "_links" then they are going use application/json and get stuff done.

It is so much more important that we build real stuff that takes advantage of hypermedia than debating the uber format. The whole point of this architecture is that it can evolve. We will learn the best ways to do stuff, once we really start doing. Pick your favourite format and go use it.

kevinswiber commented 10 years ago

@darrelmiller :+1:

Any interest in doing a quick, non-biased, independent assessment of popular JSON-based hypermedia types? "How is HAL different from Siren different from Collection+JSON?" As soon as a toe dips into hypermedia waters, I get this question. Inevitably, I will be biased. :smile:

glennblock commented 10 years ago

Good thread. My personal opinion is all these efforts are goodness. Each of the media types have their own benefits and ideal uses cases though there is overlap with some. HAL for example can be used with almost anything, but Siren and CJ bake in deeper support for specific scenarios.

Use whatever works, the web arch can easily accommodate all of them! :-) Share your experiences when you do so we can all benefit.

I think this kind of discussion is constructive so we can see the goals of each, but if I could have my druthers I would never wish for one media type to rule them all.

Thank you @mikekelly, @mamund and @kevinswiber for pushing on the space and helping us to advance our understanding!