Category Archives: rest

The Power of REST – Part 3

Last week in The Power of REST – Part 2, I talked about how investing effort in backward compatibility and having flexible settings, it’s possible to avoid a lot of “API versioning”, something Roy Fielding has decried. In this article, we’ll look more closely at the depth and power of hypermedia.

How does the web do it?

Let’s remember that REST is about bringing the scaleable power of the web to APIs. One of those classic features is “Hey, go to XYZ.com, click on ‘Books’, then click on ‘Fiction’, then click on ‘The Job’ and you can get a free copy.”

Recognize this pattern? No one can remember long URLs, but we all know about following a chain of menu items based on the shorthand text.

Hypermedia is providing links all along the way. We sometimes refer to this as a “discoverable” API. I once likened it to the classic ZORK text adventure, where you have a confined set of moves, yet can explore a very complex world.

When clients hard code URLs, updates become brittle. Everyone knows this, otherwise there wouldn’t be things like a CORBA Naming Service subspec. So when I see tools that not only support but advocate full focus on URIs, I cringe. This isn’t what REST is about.

It really is aimed at following a chain of links. Because that grants us an incredible power to migrate services.

Migrating a service

Imagine we had started things out with a service used to manage supervisors. It was basic, perhaps a tad crude. Maybe we were wet behind the ears and didn’t totally grok REST. Not a lot of hypermedia. But eventually, we migrated to a newer “manager” service.

The good news with hypermedia is that we can continue to serve data at the old URI:

If this fragment was served under the old URI, /supervisors/1, old clients could access the data found there. But with a push toward hypermedia consumption, they could navigate onto the newer version of things.

This legacy representation can be put together by the newer “manager” service to support the old clients.

This route, served to the old URI by the “manager” service, can actually retrieve information in the newer format, and repackage it as a legacy “Supervisor” record. But by supplying up-to-date links, we provide an on-ramp for clients to migrate.

Assuming we had shutdown the old “supervisor” service, the following DTO could nicely sustain the old clients until they were ready to move on up.

This immutable value type can take the new-and-improved “manager” object and extract the older representation smoothly.

Don’t argue the wrong end of things

I’ve seen a particular argument pop up in favor of REST many times. It brags about how links can change without impacting clients. Frankly, that argument comes across as lame and weak. That’s because it’s NEVER presented under the guise of backward compatibility. It’s kind of posed in a vacuum.

Building REST resources with full focus on backward compatibility, supporting old URIs and old formats, is a much stronger message in my book.

SOAP and CORBA weren’t designed to let you slip in an extra field here and there. At least, not without massive effort. It’s why no one ever did. Can you imagine going into an IDL/WSDL file and attempting to “slip in” an extra field to ease migration? It’s almost incomprehensible.

But with Jackson and robust principles applied, it’s easy to update a given route with additional data that can easily support two different clients. One REST resource supporting two clients: THAT is a strong argument. Not “links can change”.

Don’t preach it, use it

It’s why I’m giving you a sneak peek at something I’ve been wanting to write for about three months. I find myself attempting to explain the same concepts about REST on Twitter, at meetups. In Berlin, I ran into a dear friend that pinned me down and asked me hard questions on REST for over an hour. Bring it on! That affirmed my gut decision to create this:

Spring HATEOAS Examples

This repository contains several REST-based scenarios and how to implement them with Spring HATEOAS. It’s not complete. It hasn’t even been “publicly” announced, but it gives me a concentrated place to show how REST works compared to RPC-over-HTTP.

The numerous times I’ve watched Oliver defend REST, I too and picking up the banner and striving to help spread the word that if we can adopt HATEOAS and link-driven flows, we can build more sustainable systems.

For a little something to chew on, I’ll close this article with the following tweet.

https://twitter.com/olivergierke/status/458578827342794752

I strongly encourage you to click on it, and read the follow on conversation as people blink in shock “What’s wrong with Swagger?”

The Power of REST – Part 2

Last week, in The Power of REST – Part 1, I challenged someone’s proposal that their client-side query language could supplant the power of REST. It seemed to attack strawman arguments about REST. In this article, I wanted to delve a little more into what REST does and why it does it.

Basis of REST

REST was created to take the concepts that made the web successful, into API development. The success of the web, which some people don’t realize, can be summarized like this: “if the web page is updated, does the browser need an update?”

No.

When we use RCP-oriented toolkits with high specificity, one change can trigger a forced update to all parties. The clinical term for this is “brittle“. And people hate brittleness. When updates are being made, resources are no longer available.

Let’s take a quick peek at the banking industry. Despite what you think, the banking industry isn’t built up on transactions and ACID (Atomicity/Consistency/Isolation/Durability). Nope. It’s built on BASE (Basic Availability/Soft-state/Eventual consistency). An ATM machine can be disconnected from the home office, yet it will dispense cash. You can go over your limit, and still get money. But when things are made consistent, it’s you that will be paying the cost of overdrawing, not the bank.

When it comes to e-commerce, downtimes of hours/minutes/seconds can translate into millions or billions of lost dollars. (Hello, Amazon!)

Updating ALL the clients because you want to split your API’s “name” field into “firstName” and “lastName” will be nixed by management until you A) show that it doesn’t impact business or B) prove the downtime to upgrade won’t cause any loss of revenue.

Evolving an API

https://twitter.com/olivergierke/status/867819089879846914

To evolve an API, we need to reduce breakages. We need to be able to make changes to the API that WILL NOT IMPACT existing clients. Changes that allow existing clients to keep right on humming as if nothing has happened.

Eventually, they can catch up and take advantage of the new features. But only when they’re good and ready. And SOAP and CORBA were not built for this. Their definition languages (WSDL and IDL) don’t know how to be “flexible”.

But REST can. How? Let’s start with that example mentioned earlier, a resource that serves up a name. Perhaps a small piece of some e-commerce platform. You design this:

When an instance of this domain object is turned into a hypermedia-based JSON structure (through a controller we can imagine), it looks like this:

This nice bit of JSON flies around the system. You build powerful clients leveraging its vast data. Customer growth is exponential.

But suddenly, we’re victims of our own success. Your initial take on a customer representation was kind of scratched together. And now your manager darkens your door, saying, “We need first and last name. Can you do that?”

You nod and get cracking. Just need to replace name with firstName and lastName, and update all the clients. Except what you just said will incur downtime.  No, you need something a little smoother. Something that can roll out and not impact the existing clients. Instead of “versioning” your API, why not ADD TO your existing resource?

Ta-dah! Your updated domain object moves from having a single name to a first and last name, as requested. But that is not all. It also can generate that old name field, using the new data. And it can parse an incoming “name” field, turning it into your new ones.

What does this look like in JSON?

You are now sporting both the new fields AND the original one. Old clients, if they follow the conventions of REST, will simply ignore the new stuff and use the old stuff. If they need to POST an update, they know where to send it and can send just the fields they know. Your code can handle this!

Of course, you’ll have to migrate your data store before rolling this out. But again, you can maintain availability with just a LITTLE extra effort.

Honor the Robustness Principle

Be conservative in what you do, be liberal in what you accept from others.

This statement is known as the Robustness Principle. It’s what we accomplish using @JsonIgnoreProperties(ignoreUnknown = true). That annotation tells Jackson to NOT blow up when we receive an unrecognized property. Old servers can accept the new format, until they have a chance to catch up. And old clients can also talk to new servers thanks to our customized setName(wholeName) method.

By carrying around this extra sliver of information (two copies of a person’s name instead of one), we can save millions of dollars when used at scale.

And this is a core piece of REST. By avoiding antiquated concepts like versioned APIs (a requirement for CORBA and SOAP), and instead making our REST resources backwards compatible, we not only reduce downtime, we can make maintenance easier on ourselves.

If you enjoyed this, stay tuned for next week’s post, The Power of REST – Part 3, where we will dig into hypermedia.

The Power of REST – Part 1

I was kind of shocked when I saw Yet Another Posted Solution to REST. I sighed and commented, and drew the ire of many. So I figured this might be a good time to gather some thoughts on REST.

The article starts by criticizing REST and offering their toolkit as the solution. What’s really funny, is that the problems they ding are not RESTful issues.

REST requires lots of hops

Let’s start with this one:

As you might notice, this is less than ideal. When all is said and done we have made 1 + M + M + sum(Am) round trip calls to our API where M is the number of movies and sum(Am) is the sum of the number of acting credits in each of the M movies. For applications with small data requirements, this might be okay but it would never fly in a large, production system.

Conclusion? Our simple RESTful approach is not adequate. To improve our API, we might go ask someone on the backend team to build us a special /moviesAndActors endpoint to power this page. Once that endpoint is ready, we can replace our 1 + M + M + sum(Am) network calls with a single request.

This is the classic problem when you run into when fetching a 3NF (3rd normal form) data structure served up as REST.

Tip #1: REST doesn’t prevent you from merging data or offering previews of combined data. Formats like HAL include ability to serve up _embedded data, letting you give clients what they need. Spring Data REST does this through projections, but you can use anything.

In fact, server-side providers will probably have a better insight into exactly the volume of traffic fetching such data before clients. And through the power of hypermedia, can evolve to add links to the hypermedia without breaking existing clients. Old clients can do multiple hops; new clients can proceed to consume the new links, with full backwards compatibility.

REST serves too much data

If you look closely, you’ll notice that our page is using a movie’s title and image, and an actor’s name and image (i.e. we are only using 2 of 8 fields in a movie object and 2 of 7 fields in an actor object). That means we are wasting roughly three-quarters of the information that we are requesting over the network! This excess bandwidth usage can have very real impacts on performance as well as your infrastructure costs!

Just a second ago, we complained that the REST API was serving up too little data, forcing us to take multiple hops. Now we are complaining that it serves too much data and is wasting bandwidth.

The example in the article is a bit forced, given we are probably talking a couple tweets worth of data. It’s not like they are shipping 50MB too much. In fact, big volume data (images, PDFs) would best be served as links in the hypermedia. This would let the browser efficiently fetch a linked item once, and lean on the browser’s cache.

But I sense the real derision in the article is because the endpoint isn’t tailored to the client’s precise demands. No, the real example here is to illustrate a query technique on the client.

Just put SQL in the client already!

Wouldn’t it be nice if we could build a generic API that explicitly represents the entities in our data model as well as the relationships between those entities but that does not suffer from the 1 + M + M + sum(Am) performance problem? Good news! We can!

With GraphQL, we can skip directly to the optimal query and fetch all the info we need and nothing more with a simple, intuitive query.

So now we get to the real intent of the article: introduce a query language. Presumably solving REST’s straw man “problems” (which it doesn’t).

If you want to write a highly detailed query, just open a connection the data store and query directly. That’s what query languages are for. Why invent something that’s weblike, but really just Another Query Language?

What problem are you solving?

GraphQL takes a fundamentally different approach to APIs than REST. Instead of relying on HTTP constructs like verbs and URIs, it layers an intuitive query language and powerful type system on top of our data. The type system provides a strongly-typed contract between the client and server, and the query language provides a mechanism that the client developer can use to performantly fetch any data he or she might need for any given page.

This query technology may be quite handy if you must write intense, focused queries. If cutting a couple text-based columns makes that much difference, then REST may not be solution you seek. (Of course, at that point why not just have your JavaScript frontend open a SQL/MongoDB/Neo4j connection?)

What does REST solve? REST solves the brittle problem that arose with CORBA and SOAP.

REST makes it possible to evolve APIs without forcing you to update every client at once.

Think about that. When web sites make updates, does the web browser require an update? And why?

It’s no light feat of accomplishment. People were being beaten up left right as APIs would evolve. Updates were tough. Some clients would get broken. And availability is key for web scale business. So adopting the tactics that made the web resilient into API design sounds like a keen idea to try.

Too bad not enough people actually KNOW what these concepts are, and press on to criticize REST while offering “fixes” that don’t even address its fundamentals. The solution served in the article would put strong domain knowledge into the client, resulting in tight coupling. REST doesn’t shoot for this.

Am I making this assessment up?

This “virtual graph” is more explicitly expressed as a schema. A schema is a collection of types, interfaces, enums, and unions that make up your API’s data model. GraphQL even includes a convenient schema language that we can use to define our API.

Agreed. Continuing with more tight coupling instead of letting server side logic remain server side would align with SOAP 2.0, in my opinion. And it’s something I don’t much care for.

To dig in a little more about how REST makes it possible to evolve APIs with minimal impact, wait for my next article, The Power of REST – Part 2.

HTTP + REST + OAuth = say what???

In the past couple of weeks, things have really gotten hopping on the Nashville Java community’s #java slack channel. A recent topic topic of interest is how do we take something like REST, which talks about clean URIs and stateless services, and stir in this crazy OAuth stuff?

I threw in my own $0.02 given I’ve done a bit of work on projects like Spring HATEOAS and Spring Data REST. And my $0.02 is this:

HTTP + REST + OAuth should work hunky dory without compromising any of these principles.

What does this even mean?

HTTP is a spec that goes back twenty years. Or should I say, HTTP is an amalgamation of specs that goes back that long. HTTP includes the request/response protocol, the verbs (GET, POST, etc.), the concept of media types, content negotiation, and more. At the heart of MANY of these specs is none other than Roy Fielding. Yes, the man that wrote his doctoral dissertation on REST had his fingers in a dozen specs that governs how the Internet operates.

REST is doctoral dissertation that was published in 2001. REST not a spec, not an API, not a standard. It’s an idea. An idea that if similar constraints that existed for the web plus a few others were adopted when building Internet-based services, then they too could enjoy the scalability and fault tolerance the web has come to enjoy.

OAuth is an 11-year-old security protocol driven by the explosion of 3rd party social media applications that were requiring users enter their credentials so the apps could log into social media networks on their behalf. It introduces a flow whereby the app, instead of gathering credentials, would take the user over to the source site, have them login there, be issued a token, and thereafter use the token in lieu of actual credentials.

All of these concepts have grown supreme in applications today. Enterprise shops want big apps to support millions of customers, and they want them yesterday. Hence the desire for scale.

We’re all aware of how the web was won the war of the UI. I remember coding Swing apps in data centers, and side stepping the growth of the web, but the web has beaten thick client apps hands down. The only REAL thick client app are the apps found on mobile devices. The standards of web apps is front and center.

EVERYONE wants OAuth. I’ve often stated “it isn’t real until it’s secured” indicating that frameworks without a security solution will get passed over by production shops. That’s because no customer will talk to you unless your solution can be secured. And with the rise of mobile apps and multiple clients talking to a backend, the need for OAuth is gigantic.

So how does this mishmash of ideas all fit together without tragic compromise? Let’s take things apart.

Fundamentals of REST

One of the most fundamental concepts behind REST is to include not just data in the payload, but links to resources from which you can DO SOMETHING with the payload. Or links to a state you can transition toward. For example, a Coffee Shop API that let’s you place orders should include a link to cancel the order WHEN IT’S POSSIBLE. By pushing the link to the human user, they can see when they can/can’t do that. Hence the rise of media types that support including links. For example, the JSON document below shows HAL, with both data and links.

{
  "firstName" : "Frodo",
  "lastName" : "Baggins",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/persons/1"
    },
    "address" : {
      "href" : "http://localhost:8080/persons/1/address"
    }
  }
}

That’s nice, but what do we do when this data needs to be wrapped with OAuth?

OAuth, as briefly stated, is a flow where the website redirects the client to a login page, potentially at a different site altogether. A token is issued, and then we go back to the original site. Now we have a token in hand.

This token nicely fits into an HTTP Authorization header like this:

Authorization: Bearer 0b79bab50daca910b000d4f1a2b675d604257e42

If you’ll notice, I said header. HTTP headers don’t infringe upon payloads designed to support REST. HAL doesn’t have to know that the service is protected by OAuth + whatever other security protocols are layered on. Security, as they say, is orthogonal.

That’s because HTTP includes options to extend itself. HTTP has room for new media types (application/hal+json and application/hal+xml), new headers (Authorization), and new payloads.

And why shouldn’t we expect this? The man involved with designing the web also designed REST. Someone trying to take lessons learned from the web and apply them to APIs would surely work to fit it into the nature of the web.

To approach a secured service, I make the call, and if I get a 302 redirect to a login page, my client can come back to the human user and indicate that there is security required. At this stage, it would be completely normal to SHOW the human the login page. Let the user supply what’s needed, and my client should be able to harvest the token, and press on.

Should security be a part of the REST representation?

Yes and no. Security protocols aren’t required to be there. That would clutter up the nature of data and navigation. And clients shouldn’t be giving away any secrets, whether that is a bearer token or credentials.

But hypermedia links should be VERY sensitive to the nature of the client and serve different sets of links based on what the client is allowed to do. If the client will be declined attempting to perform a DELETE, then don’t show them the link to do it.

REST and stateless services

People like to regurgitate this REST-ism about “no state no state no state”. Yet when we get into the subject of security and the STATE of the user’s logged in nature, some people go nuts. Being stateless means that my next REST request should be able to get routed to any server on the backend. In a cloud native environment, there could be twenty copies right now, fifty five minutes from now, and two copies ten minutes after that.

The state of my next REST operation shouldn’t require I go back to the same server. If the server is feverishly trying to push session details around between gobs of servers, that is crazy. That’s why toolkits like Spring Session offer the option to use either cookies or headers. It’s possible to log into a system, get some form of session, offload the session state to a 3rd pary service, like Redis, and then bounce off of that using a header.

As Rob Winch states in the video below, a little bit of state is alright. When done like this, where you security state is managed properly in a data store and NOT on the server itself, you’ll do fine.

So wrap things up, serving up things over the web, securing them with modern practices, while also having scalable APIs should fit together nicely. Because the web was built for flexibility and extensibility, if we just embrace all of its paradigms.

REST, SOAP, and CORBA, i.e. how we got here

I keep running into ideas, thoughts, and decisions swirling around REST. So many things keep popping up that make me want to scream, “Just read the history, and you’ll understand it!!!”

wayback-machineSo I thought I might pull out the good ole Wayback Machine to an early part of my career and discuss a little bit about how we all got here.

In the good ole days of CORBA

This is an ironic expression, given computer science can easily trace its roots back to WWII and Alan Turing, which is way before I was born. But let’s step back to somewhere around 1999-2000 when CORBA was all the rage. This is even more ironic, because the CORBA spec goes back to 1991. Let’s just say, this is where I come in.

First of all, do you even know what CORBA is? It is the Common Object Request Broker Architecture. To simplifiy, it was an RPC protocol based on the Proxy pattern. You define a language neutral interface, and CORBA tools compile client and server code into your language of choice.

The gold in all this? Clients and servers could be completely different languages. C++ clients talking to Java servers. Ada clients talking to Python servers. Everything from the interface definition language to the wire protocol was covered. You get the idea.

Up until this point, clients and servers spoke binary protocols bound up in the language. Let us also not forget, that open source wasn’t as prevalent as it is today. Hessian RPC 1.0 came out in 2004. If you’re thinking of Java RMI, too bad. CORBA preceded RMI. Two systems talking to each other were plagued by a lack of open mechanisms and tech agreements. C++ just didn’t talk to Java.

CORBA is a cooking!

advanced-corbaWith the rise of CORBA, things started cooking. I loved it! In fact, I was once known as Captain Corba at my old job, due to being really up to snuff on its ins and outs. In a rare fit of nerd nirvana, I purchased Steve Vinoski’s book Advanced CORBA Programming with C++, and had it autographed by the man himself when he came onsite for a talk.

Having written a mixture of Ada and C++ at the beginning of my career, it was super cool watching another team build a separate subsystem on a different stack. Some parts were legacy Ada code, wrapped with an Ada-Java-CORBA bridge. Fresh systems were built in Java. All systems spoke smoothly.

The cost of CORBA

Boring PresentationThis was nevertheless RPC. Talking to each other required meeting and agreeing on interfaces. Updates to interfaces required updates on both sides. The process to make updates was costly, since it involved multiple people meeting in a room and hammering out these changes.

The high specificity of these interfaces also made the interface brittle. Rolling out a new version required ALL clients upgrade at once. It was an all or nothing proposition.

At the time, I was involved with perhaps half a dozen teams and the actual users was quite small. So the cost wasn’t that huge like today’s web scale problems.

Anybody need a little SOAP?

soapAfter moving off that project, I worked on another system that required integrate remote systems. I rubbed my hands together, ready to my polished CORBA talents to good use again, but our chief software engineer duly informed me a new technology being evaluted: SOAP.

“Huh?”

The thought of chucking all this CORBA talent did not excite me. A couple of factors transpired FAST that allowed SOAP to break onto the scene.

First of all, this was Microsoft’s response to the widely popular CORBA standard. Fight standards with standards, ehh? In that day and age, Microsoft fought valiantly to own any stack, end-to-end (and they aren’t today???? Wow!) It was built up around XML (another new acronym to me). At the time of its emergence, you could argue it was functionally equivalent to CORBA. Define your interface, generate client-side and server-side code, and its off the races, right?

But another issue was brewing in CORBA land. The OMG, the consortium responsible for the CORBA spec, had gaps not covered by the spec. Kind of like trying to ONLY write SQL queries with ANSI SQL. Simply not good enough. To cover these gaps, very vendor had proprietary extensions. The biggest one was Iona, an Irish company that at one time held 80% of the CORBA marketshare. We knew them as “I-own-ya'” given their steep price.

CORBA was supposed to cross vendor supported, but it wasn’t. You bought all middleware from the same vendor. Something clicked, and LOTS of customers dropped Iona. This galvanized the rise of SOAP.

But there was a problem

SOAP took off and CORBA stumbled. To this day, we have enterprise customers avidly using Spring Web Services, our SOAP integration library. I haven’t seen a CORBA client in years. Doesn’t mean CORBA is dead. But SOAP moved into the strong position.

Yet SOAP still had the same fundamental issue: fixed, brittle interfaces that required agreement between all parties. Slight changes required upgrading everyone.

When you build interfaces designed for machines, you usually need a high degree of specification. Precise types, fields, all that. Change one tiny piece of that contract, and clients and servers are no longer talking. Things were highly brittle. But people had to chug along, so they started working around the specs anyway they could.

I worked with a CORBA-based off the shelf ticketing system. It had four versions of its CORBA API to talk to. A clear problem when using pure RPC (CORBA or SOAP).

Cue the rise of the web

Around-the-webWhile “rise of the web” sounds like some fancy Terminator sequel, the rampant increase in the web being the platform of choice for e-commerce, email, and so many other things caught the attention of many including Roy Fielding.

Roy Fielding was a computer scientist that had been involved in more than a dozen RFC specs that governed how the web operated, the biggest arguably being the HTTP spec. He understood how the web worked.

The web had responded to what I like to call brute economy. If literally millions of e-commerce sites were based on the paradigm of brittle RPC interfaces, the web would never have succeeded. Instead, the web was built up on lots of tiny standards: exchanging information and requests via HTTP, formatting data with media types, a strict set of operations known as the HTTP verbs, hypermedia links, and more.

But there was something else in the web that was quite different. Flexibility. By constraining the actual HTML elements and operations that were available, browsers and web servers became points of communication that didn’t require coordination when a website was updated. Moving HTML forms around on a page didn’t break consumers. Changing the text of a button didn’t break anything. If the backend moved, it was fine as long as the link in the page’s HTML button was updated.

The REST of the story

The-Rest-of-the-StoryIn his doctoral dissertation published in 2000, Roy Fielding attempted to take the lessons learned from building a resilient web, and apply them to APIs. He dubbed this Representational Transfer of State or REST.

So far, things like CORBA, SOAP, and other RPC protocols were based on the faulty premise of defining with high precision the bits of data sent over the wire and back. Things that are highly precise are the easiest to break.

REST is based on the idea that you should send data but also information on how to consume the data. And by adopting some basic constraints, clients and servers can work out a lot of details through a more symbiotic set of machine + user interactions.

For example, sending a record for an order is valuable, but it’s even handier to send over related links, like the customer that ordered it, links to the catalog for each item, and links to the delivery tracking system.

Clients don’t have to use all of this extra data, but by providing enough self discovery, clients can adapt without suffering brittle updates.

The format of data can be dictated by media types, something that made it easy for browsers to handle HTML, image files, PDFs, etc. Browsers were coded once, long ago, to render a PDF document inline including a button to optionally save. Done and done. HTML pages are run through a different parser. Image files are similarly rendered without needing more and more upgrades to the browser. With a rich suite of standardized media types, web sites can evolve rapidly without requiring an update to the browser.

Did I mention machine + user interaction? Instead of requiring the client to consume links, it can instead display the links to the end user and let he or she actually click on them. We call this well known technique: hypermedia.

To version or not to version, that is the question!

HamletA question I get anytime I discuss Spring Data REST or Spring HATEOAS is versioning APIs. To quote Roy Fielding, don’t do it! People don’t version websites. Instead, they add new elements, and gradually implement the means to redirect old links to new pages. A better summary can be found in this interview with Roy Fielding on InfoQ.

When working on REST APIs and hypermedia, your probing question should be, “if this was a website viewed by a browser, would I handle it the same way?” If it sounds crazy in that context, then you’re probably going down the wrong path.

Imagine a record that includes both firstName and lastName, but you want to add fullName. Don’t rip out the old fields. Simply add new ones. You might have to implement some conversions and handlers to help older clients not yet using fullName, but that is worth the cost of avoiding brittle changes to existing clients. It reduces the friction.

In the event you need to REALLY make a big change to things, a simple version number doesn’t cut it. On the web, it’s called a new website. So release a new API at a new path and move on.

People clamor HARD for getting the super secret “id” field from a data record instead of using the “self” link. HINT: If you are pasting together URIs to talk to a REST service, something is wrong. It’s either your approach to consuming the API, or the service itself isn’t giving you any/enough links to navigate it.

When you get a URI, THAT is what you put into your web page, so the user can see the control and pick it. Your code doesn’t have to click it. Links are for users.

Fighting REST

fight1To this day, people are still fighting the concept of REST. Some have fallen in love with URIs that look like http://example.com/orders/523/lineitem/14 and http://example.com/orders/124/customer, thinking that these pretty URLs are the be-all/end-all of REST. Yet they code with RPC patterns.

In truth, formatting URLs this way, instead of as http://example.com/orders?q=523&li=14 or http://example.com/orders?q=124&mode=customer is to take advantage of HTTP caching when possible. A Good Idea(tm), but not a core tenet.

As a side effect, handing out JSON records with {orderId: 523} has forced clients to paste together links by hand. These links, not formed by the server, are brittle and just as bad as SOAP and CORBA, violating the whole reason REST was created. Does Amazon hand you the ISBN code for a book and expect you to enter into the “Buy It Now” button? No.

Many JavaScript frameworks have arisen, some quite popular. They claim to have REST support, yet people are coming on to chat channels asking how to get the “id” for a record so they can parse or assemble a URI.

BAD DESIGN SMELL! URIs are built by the server along with application state. If you clone state in the UI, you may end up replicating functionality and hence coupling things you never intended to.

Hopefully, I’ve laid out some the history and reasons that REST is what it is, and why learning what it’s meant to solve can help us all not reinvent the wheel of RPC.