We like to build things here at Potato. We also like to eat. A lot.
So here’s the story about how we managed to merge those two passions into one project.
One of the perks of working at Potato is free food every lunchtime, sourced from a range of local outlets. This is delivered to your desk too, in case you’d prefer to plough on with coding without keeling over from hunger.
But we had to figure out an efficient way of collecting the staff’s orders every day, so what more obvious way for a tech shop to address this, than to build our own app?
We like to call it our Wallace and Gromit approach: why do a predictable task manually when you can build something to do it for you?
And so Bytes was born.
Built by senior dev David Buxton and former intern Thomas Purchas, this is an all-in-one, menu-scraping, order-taking, food-organising webapp. It was built using django-nonrel on the backend, and Backbone.Marionette on the front. As with many of Potato's apps, this is deployed onto Google App Engine and secured to our domain using Google Apps.
Using Backbone models, it was simple to store the entire order state on the server.
Every time an item is added or removed from the order, a quick AJAX request is fired to inform the server. This is all powered by simple Backbone model saves.
The use of Backbone also made it relatively easy to use polling in order to keep multiple clients in sync. Although simple to implement, polling is not efficient, and given more time we would have tried using App Engine’s Channel API (since deprecated) or the newer Firebase APIs.
This results in some rather heavy artificial traffic, as a frenzy of hungry coders hit it simultaneously from a wide variety of devices. App Engine, of course, eats this up it like a champ.
For styling, good old Bootstrap was called upon to keep things responsive. This also made building the UI simple, and kept it smooth and usable on tablets and other smaller form factors.
On the backend, Django was used almost entirely for its models, and the Django REST Framework, which did most of the work, providing a neat Backbone compatible API.
There was also some heavy use of Memcached to deal with the polling. The API endpoint that gets polled is heavily cached, and due to this polling the Memcached stats show a rather silly 99% hit rate. Later we de-normalised the order data so it would be faster to read from the datastore, which gave another speed boost to the API.
Chain restaurants! Expose your menus in an API. We'll buy more food from you— Jason Cartwright (@jasoncartwright) January 16, 2017
The backend also handles scraping the local eateries for their menus, ensuring that things like soups of the day are kept up-to-date. The excellent lxml Python library is used to dissect each shop's online menu and deal with the inevitably garbled HTML.
The app spits out printable reports by shop for ordering; then when the food gets back to the office, Bytes produces a page sorted by person for efficient delivery to the correct desk. How much more convenient can you get?