89-year-old family butcher's to close due to soaring overheads
MI5 send New IRA 'Spotify-wrapped' style video message urging them to quit in wake of latest car bomb attack outside Belfast police station
Tributes to Essex influencer as X Factor star charged with murder
Tributes to Essex influencer as X Factor star charged with murder
Why coachloads of Chinese tourists are flocking to your favourite beauty spot
PowerPoint punishment sent users into an infinite loop after lunch
Who, Me? Welcome to another instalment of Who, Me? It's The Register's Monday column that shares your stories of mistakes, occasional malice, and how you came out the other side.…
Exact date popular Maldon splash park will reopen for the summer
Woman and man rushed to hospital after being attacked in their Clacton home
Powerful 6.4-magnitude earthquake shakes northern Japan a week after huge tremor sparked tsunami and megaquake warning
Trump says extremists are 'radicalized' by Democrats and condemns 'hate speech after assassination attempt at White House Correspondents' Dinner
Mentalist Oz Pearlman reveals what he was showing Melania Trump on notepad in seconds before shots rang out at White House Correspondents' Dinner
Counter-terror police make further arrest of man, 37, in rural Devon after spate of attacks on Jewish synagogues
CodeSOD: The JSON Template
We rip on PHP a lot, but I am willing to admit that the language and ecosystem have evolved over the years. What started as an ugly templating language is now just an ugly regular language.
But what happens when you still really want to do things with templates? Allison has inherited a Python-based, WSGI application which rejects any sort of formal routing or basic web development best practices. Their way of routing requests is simply long chains of "if condition then invokeA elif otherCondition then invokeB". Sometimes, those conditions will directly set the MIME type on the HTTP response.
They do use a templating library called Mako for generating their responses. They use it for their HTML responses, obviously. They also use it for their JSON responses, generating code like this:
{ "success": true, "items": { %for item in items_available.keys(): "${item}": ${items_available[item]}${',' if not loop.last else ''} %endfor } }The %for and matching %endfor mark the Python code off, which generates JSON via string-munging, complete with the check to make sure we're not on the last iteration of the loop.
Like so much bad code, this offers a degree of fractal wrongness. Instead of iterating over the keys and fetching the items inside the loop, you could iterate for key,value in items_available.items()- and according to the Mako docs, that for is just a regular Python for loop. That we're just outputting the contents of the dictionary is itself potentially a problem- sure, if we know the types of the dictionary, we'll know that whatever it is can be output in the body of a JSON document, but do we really think this code is using type annotations? I don't. And for a RESTful web service, I'm always going to feel weird about using a success field when ideally the HTTP status code could convey most of that information (and yes, I know there are reasons to still put status in the body, I just hate it).
Of course, the real issue is just: Python's built in JSON serialization is actually pretty advanced. And performant! You don't need any of this, you could just do something like:
return json.dumps({"success": true, "items": items_available})No templates. No formatting. No worries about how the data gets represented. Well, still worries, because JSON serialier will throw exceptions if it doesn't know what to do with a type. But then at least you get that exception on the server side and aren't sending the client a malformed document.
In any case, this is a good demonstration that you can write bad PHP in any language.