For some background, the application that motivated this post is one that displays a map with markers for various events. Clicking on a marker brings up information about the event. The data to populate the map is provided by a backend API, which responds to queries with JSON objects. However, those JSON objects were just blocks of HTML elements wrapping the requested data.
For example GET /data/event -d '{"id":12345}'
would return something like this:
{
"response":
"<div id=\"eventId\">
<h1>Event name</h1>
<span=\"eventSubmitter\">Submitted by John Smith</span>
<span=\"eventDetails\">Blah blah blah</span>
</div>"
}
The application used AJAX to process the API request, and used Javascript to insert the raw response into a div
element. This is quite literally the dumbest design I’ve seen in a long time.
A Metaphor
Imagine you’re tasked with building a simple, single level home. How would you go about it? You would probably start by laying a foundation, then putting up your framing studs and install some plywood around the exterior. You would add your plumbing and electrical lines, then probably start adding your insulation and putting up drywall. You’d lay your carpets, install lighting and plumbing fixtures, caulk and seal as needed. Then you’d add decorative elements, slap a coat of paint on it and call it a day. Hopefully you’ve done quality work according to applicable building codes.
But what if later, you decide the carpets are ugly or the paint is dated? That’s easy: you’d simply change them. Rip out the carpets and put in new ones. Repaint whatever you like. It’s not complicated.
The reason it’s not complicated is that the structure of the house is decoupled from its presentation. That is, there is no interdependance between how it’s built and how it’s decorated. The color of a wall is not related to the distance between its framing studs. As a result, we can trivially change the presentation of the home quickly and efficiently.
Back to the API of Shit
Returning to the API in question, I’m sure that one of the developers figured it was more expedient because it requires less client-side logic to be performed. I imagine the arguments in favor of this approach would be involve claims about bandwidth savings by not forcing the user to download presentational logic scripts. Maybe even something about devices with limited hardware resources. Cheaper hosting, good for mobile users, etc. But this is total bullshit.
For one, the markup that’s left out of the page loading will eventually make its way over the network via the markup in the JSON body. For some number of markers, the markup costs will outweigh simply downloading presentational logic when the page is loaded. Even if that weren’t the case, that approach to saving a few kilobytes prevents the developer from making even minor changes to the application.
The other problem is that if anyone wants to use the API, they’ll need to write a custom wrapper to remove the HTML elements and translate it into an actual JS object. Why is this a problem? What if another company wants to license your product and pay you a boatload of money for API access? Are you going to build and maintain separate APIs for each possible case?
In the context of our physical house, imagine if the color of the walls really was coupled to the spacing of the studs. Want to change the color of a room? You’re going to need to demolish and completely rebuild that part of the house. Want to add a room? You’ll need to decide what color it will be first, because once it’s built the only way to change the color will be to completely demolish it and rebuild.
It reminds me of this classic Simpsons episode with the “load-bearing poster”:
How terrible would that be? How would you feel about an architect who came up with those rules? How about when he says: “Yeah, but I saved you one man-hour of work this way!”
Most people would fire that architect and hire someone who’s not a complete idiot. And honestly, software design should be no different.
Avoid stupid shortcuts
The power and flexibility of code gives software developers just enough rope to hang themselves. Especially in the early days of a project, expediency often means locking the application into bad patterns that will affect it for its entire lifecycle. Best practices and design patterns were developed specifically to avoid these kinds of problems, and it’s a really good idea to stick with them.
“Done is better than perfect” is not an excuse to push out some garbage protoduction and call it a day; devs should take the same forethought and care with their work as the team that built their house. And if you have a poorly-designed house already, then you should appreciate even more why this kind of approach is unacceptable.