It's a confusing year to be a voter in New York City.
Although the race for Mayor Michael Bloomberg's successor has dominated headlines, term limits and redrawn political districts have reshaped the contours of many of the city's less prominent local races, giving voters new and unfamiliar choices to make as they head to their polling places for next week's general election.
We built The Other Races, an interactive feature for this year's local elections, to help voters make sense of this new political geography. After a user enters an address, the application returns a listing of candidates who are up for election in local political districts and points to resources, such as candidate statements and social media accounts, to help voters learn more.
The project is a nod towards Represent, a tool we first launched in December 2008. From a technical perspective, resurrecting a five-year-old app gave us the chance to see which parts of our app development processes have evolved and which have stayed largely the same.
Initially, Represent was a dynamic app built using Django and its spatial toolkit, GeoDjango. The app provided its own geocoding and district lookup logic, which required a considerable amount of computing power. As with many news apps of the time, it was largely served dynamically, fronted by a cache for speed and reliability.
The Other Races, on the other hand, is much more reliant on web services (both internal and external) and static files served through our content-delivery network. In fact, the app is now almost completely client-side, built with a thin layer of Backbone.js that collects and manages all the resources coming in from various APIs.
When a user enters an address, the interactive feature geocodes it using Google's Geocoding API. It then queries a separate Times API of political district boundaries, which returns a list of all the districts containing the coordinates, along with their geographic outlines in KML format. Finally, it uses Google Maps to draw a map of each district. The Districts API was carried forward from the original Represent and powers several of our other projects as well.
The initial version of The Other Races was a very light Sinatra app. A simple web form recorded the address before the back end chained API calls and scraped together articles, tweets and other contextual resources collected dynamically when the page was rendered. This data was pulled together and baked into an HTML file, served up without any fancy trimmings.
It was clear that most of the logic could be pulled from the back end to the front end using Backbone. We also learned that for things like City Council races, which seldom make headlines, much of the content we were scraping was irrelevant, out-of-date or both. So instead of collecting data programmatically, we asked our editorial team to write and select content they thought would put these local races in context.
To enter the content, editors and reporters used an internal tool called DataVault, which provides a user-friendly spreadsheet interface but outputs JSON files for our applications to ingest. By removing Sinatra and any other back end logic, Represent had finally completed its evolution, morphing from a dynamic application to a simple set of HTML, CSS and JavaScript files that could be served through a CDN.
Although the simplicity of The Other Races is not achievable in many cases (for example, the interactive feature would not have been possible without the already stable Districts API), completely divorcing the display and data logic has some definite advantages. The separation meant that concerns about load-balancing or caching were almost entirely out of scope while I was working on The Other Races. Storing content for The Other Races with a spreadsheet allows for easy customization to fit different election scenarios.
Kiran Bhattaram was a summer intern with Interactive News.
No comments:
Post a Comment