So I've decided to switch from Java on the server to Python instead. Basically, before I was using Restlet to implement the API and GWT for the UI. The UI is really only the "Admin interface" that I will be using to perform administrator functions (banning users, manual examination of data for debugging and whatnot). Now I'm using Python, with Protocol Buffers as the "glue" between the client and server (obviously, the Android client is still Java).
In addition, I've stopped using Restlet in the Android client as well, opting instead to use "raw" HttpCore. I've written my own little API for fetching, putting, posting and deleting protocol buffers based on URLs (the server is still REST-"like")
So why did I do it? It's true that using Restlet lets you implement an API with barely a thought to the underlying technology, but personally I found it suffers a problem common with a lot of Java APIs –- layer upon layer of abstraction. It makes it very hard to guess what's actually going on under the covers, and I like to know what's going on under the covers!
Now, my python server is built directly on top of the webapp2 API (yes, that means I'm using the "experimental" Python 2.7 runtime – hopefully it'll no longer be an "experiment" by the time my game is actually released!), and there's very little in the way of abstraction – which is just how I like it.
One thing I liked from Restlet was the automatic Content-Type negotiation. So I've added my own version, albeit much simpler. Basically I look at the Accept header: is there's a mention of "application/x-protobuf", I return a protocol buffer; if we see "application/json" we return a JSON serialization; otherwise, we return the result of str(PB)
(where "PB" is the protocol buffer Message
, of course).
Then, because I control all the clients, the Android app always requests with Accept: application/x-protobuf
. The JavaScript client (which is part of the web-based "admin" interface I mentioned earlier) always requests with Accept: application/json
. And the other option is just so I can issue GET requests with my browser for testing.
My webapp2 handlers return the protocol buffer object directly, and the base handler class will determine how to serialize the object. I wrote my own Protocol Buffer -> JSON converter in Python which I'll cover in a follow-up post, but it's actually really simple (thanks to Protocol Buffer's self-describing nature).
The end result is a lot greater control over the whole process, and a lot less boilerplate code required. In fact, it took me about a week to re-implement the functionality of the old server in Python (keeping in mind I work only evenings/weekends, and in between various other jobs I have!)
To begin with, I was kind of excited to try out GWT on the server, but after having used it – though briefly – I'm glad to leave it behind. The admin interface is really basic, and since I'm pretty much the only person who will ever use it, I think GWT was way overkill.