Because machines still need humans
URI construction: give it a REST
September 7, 2011Posted by on
Picture the scene: you’ve just updated your product’s REST API. You’ve added lots of new features, revamped the URI structure and you’re excited for your clients to start using it.
One of these two things will happen within the hour:
- Your support line will ring off the hook with angry customers screaming about how none of their applications are working anymore, and how they’re going to wring your neck for breaking their systems at the worst possible time.
- Everything works great and your customers send you chocolates in gratitude for the new features.
The problems in #1 will occur if your customers do any kind of URI construction in their REST API client applications. That innocuous “revamping” of your URI structure has just broken all the clients who were tightly bound to the exact format and layout of your old URIs.
Imagine an API for an online entertainment company (let’s call them Fun.com) that streams both movies and music. Thankfully, the folks at Fun.com have learned enough about REST that they only guarantee a long life for the top-level URI (https://api.fun.com). That means that well-behaved clients will hard-code just that single entry-point, and will only follow other URIs that are returned to them as part of their normal interactions beyond that point.
In their API documentation, they say that to get a listing of the available movies on their site you must first GET the top-level URI, and then look for the link listed as “Movies” in the returned payload (defined by its media type). They don’t say what that link’s format or value will be, but they are very clear that it’s the one to follow if you want to get the list of movies:
So far, so good!
Now the team at Fun.com decides to branch into lots of diverse markets, so the API designers start to organize the URI structure a little to prepare for the new services. They move both movies and music into their own “entertainment” area and deploy the new API. Thankfully all the well-behaved REST clients are unaffected, because they don’t care about the URI formats at all – they always start at the entry-point and navigate their way around:
Unlucky for the folks at Fun.com, one of their biggest customers used a hacker coder to write their API client, and he broke the URI construction rule. He saw the original URI format and thought to himself, “Why should I waste time always going to the top-level and asking where the movie listings are when I can see the URI for them already? I’m just going to hard-code in the movies URI and that will make the application run way faster!”
Sadly, his application is now completely broken:
He made the mistake of directly coupling his application with the structure of the URIs and ended up breaking his system in the process.
Why is URI construction a common problem?
Encounters with hard-coding hacks like this are not rare, for a number of reasons:
- Plenty of RESTful API vendors don’t do a good job of discouraging URI construction in their documentation. Typically, they list all the URIs for their resources rather than focus on the media types which will contain them.
- Sample code and demos aren’t usually provided, leaving clients to figure out for themselves what the “best practices” are for calling their API.
- URIs have a human-readable, well-understood format and programmers are used to typing them into browser address bars. That leads to an understandable inclination to do the same with RESTful URIs. If clients had to instead deal with MD5 hashes, UUIDs or long hexadecimal numbers, this problem simply wouldn’t exist. Nobody expects a C++ pointer address to be the same every time a process runs, but unfortunately the same understanding isn’t usually applied to RESTful URIs.
What can be done about it?
You can’t prevent URI construction attempts. What you can do, however, is:
- Document the correct usage of your API through its media types rather than its URIs. Explain that URI structure is a convenience that benefits the providers of the service more than the programmers who consume it.
- Provide sample code which demonstrates best practices (and don’t forget that your sample code will likely go into production).
- Talk to your clients and educate them about your API before they build applications with it. REST APIs aren’t magic, and can still be misused.
If coders out there could give URI construction a REST, everyone could rest easy when the APIs evolve. Let’s make it happen.