We’re currently developing a REST API and we’d like to open up the process for your feedback.
The More You Know…
When we first started learning about the REST + Hypermedia (HATEOAS) style of software architecture, it became apparent how much we didn’t know. Hours (then days, then weeks and months) were spent reading Fielding’s work, consuming blog posts, participating in Google Groups, watching webinars, and hunting for conference videos. Endless dialog ensued. We began to understand generic media types aren’t very helpful (what does “application/json” or “application/xml” really tell us about the resource the client needs to consume other than how to parse it?). We learned about a standard for vendor specific media types (such as vnd.foxycart.com.store+json). We further discovered various methods for versioning those media types so they could be completely defined and yet change over time without breaking existing clients (and thus we have vnd.foxycart.com.store+json;version=1).
We liked JSON but realized there was no standard for how to represent hypermedia. XML has Atom links, which most people seem to favor, but JSON was still in flux. The two main contenders at the time appeared to be Collection+JSON and HAL. We almost decided to ditch a vendor specific media types in favor of these, but were confused how the client would know what they were getting back, other than a data payload stuffed inside a known hypermedia-ready envelope.
There was no single API someone could point to and tell us, “Do it like that. That’s a perfect REST API.”
Choosing a Standard
After about two months of research, learning all we could, we finally decided to go build something. As Wikipedia says, “there is no ‘official’ standard for RESTful web services. This is because REST is an architectural style, unlike SOAP, which is a protocol. Even though REST is not a standard, a RESTful implementation such as the Web can use standards like HTTP, URI, XML, etc.” Now the question becomes, what standards should our API use?
We decided to go with HAL’s hypermedia format because we liked the ability to jump right to the intended link via _links.{rel}.href where {rel} is the link relation you’re looking for. We pulled back from the research and got busy building out resources. Months and months of development, writing new end points and test cases for them all. We were just about done when along came RESTfest, 2012.
Rethinking Everything
What an awesome experience! It was great to hang out with guys like Mike Amundsen, the author of O’Reilly’s “Building Hypermedia APIs with HTML5 and Node” and the creator of Collection+JSON. To play Cosmic Encounter with Leonard Richardson, the author of O’Reilly’s “RESTful Web Services” and well known for what’s being called the Richardson Maturity Model for REST. The whole event was jam packed with me (Luke) asking questions of these industry leaders about the approach we’ve taken and what the best practices are.
Stu Charlton, the keynote speaker, spent some time helping me realize we could go with a more generic media type such as Collection+JSON, HAL or Siren (Kevin Swiber, Siren’s creator was there also), if we use the custom link relation as the point of clarity. Client developers will already have to read our documentation to understand our custom link relations and code against them. If they know what to expect back from a https://api.foxycart.com/rels/store relation, then why would we need to clarify it further with a vnd.foxycart.com.store+json media type? This seemed to be the “Ah Ha!” moment I was looking for.
I left the conference feeling confident about ditching our “media type for every resource” approach and going with one of the leading JSON-based formats. But then I started having some conversations in #rest on irc.freenode.net and was further challenged in my thinking. HTML, as a standard, had a very specific problem domain (the WWW). HAL, Collection, etc… are they too generic to be very useful? I started thinking about proposing our own media type for ecommerce. Building off of existing work like GoodRelations, the idea would be to pave the way for interoperability between commerce systems. Let developers build clients that would work with multiple shopping cart APIs (at last count, programmable web listed 71, though, to be fair, many of them are gateway APIs, not shopping carts).
That got me really excited about doing things right and setting us up as a thought leader in the industry. We have thousands of stores looking to us already for guidance and structure as it pertains to ecommerce and the model we have has served them well. Who’s to say we shouldn’t be the ones to develop and propose a standard?
The options:
So that’s where we are now. Here are the options before us:
- Continue as we have been and launch with a custom vendor media type for every single resource and collection of resources in our system.
- Go with something generic like Collection+JSON, HAL or Siren while potentially ditching XML all together or standardizing on AtomPUB with our own defined namespaces. Tell people to code against the rel’s and read the documentation as needed.
- Go with a single vendor specific media type like vnd.foxycart.com+json that covers and defines all of our collections and resources along with some form of JSON hypermedia people like.
- Propose an entirely new standard such as application/ecommerce and go through the process of registering that media type.
And the challenges (by number, above):
- I’ve already been told by a lot of people this is kind of a stupid way to go. Granted, some smart people out there like GitHub have done this, but it may not add value to the ecosystem. My thought is we could, eventually, compare and contrast our super-specific vendor media types with other ecommerce organizations and, hopefully, move toward a standard. Some day. Eventually. Yeah. You’re right. It’s a long shot.
- This sounds good, but what about when we want to change things? If I code to https://api.foxycart.com/rels/store and I expect a very specific data payload back, what happens when we add a new store property? Ideally, clients can adjust to additive changes, but what if we have to make a breaking change such as moving something to a sub resource? Would this require an API-wide version change? Also, which one should we go with? They all have things I like, but they are all slightly different (especially in regards to their hypermedia format). I like how Siren attempts to conform to the existing Web Linking RFC rules, but Siren appears to be a little newer than the others. Who’s to say what will come out next month?
- This has the same concern as #2 regarding introducing new changes… it also may not help the developer code things. If there’s just a sea of resources, collections and attributes that can be stuffed into one gigantic media type from stores to users to transactions to products to coupons to subscriptions… will that just be messy?
- This is probably the “purest” approach… but is it the most practical or pragmatic? Though we do have a lot of experience, do we have a enough? Could we possibly promote a standard others would find useful and agree to use? What about changes to that standard? How many times has HTML changed over the years (and how slowly)? We’d probably need to change a lot more and a lot faster.
So where does that leave us? We’re leaning towards going with #2 and Siren, but we’re open to suggestions.
What do you think?