Google App Engine was released to a lot of fanfare. App Engine promised easy application deployment and management. App Engine is not so much a framework as it is an infrastructure power by Google. I have been looking for a simple development and deployment solution for micro-web applications so I gave Google App Engine a try.
My first App Engine application would be as simple as possible. I wanted to micro-web application like Tumblr or Twitter so that I could simple post quotes. Since the best way to learn is by example, I grabbed a sample Google App Engine project. The sample project I used as a basis was a mix of App Engine models and Django forms.
When working on a App Engine application, the first step is to define your models. The application I have in mind has one Quote model and I defined it as follows.
# Should be required, should default to logged in user…
user = db.UserProperty(required=False)
quote = db.StringProperty(required=True)
source = db.StringProperty(required=True)
created = db.DateTimeProperty(auto_now_add=True)
modified = db.DateTimeProperty(auto_now=True)
Google App Engine has its own query language commonly refereed as GQL. GQL is like SQL except I found its parser more strict and temperamental. You can use GQL to persist and retrieve instances of your model, for example for my model I used the following GQL query.
quotes = db.GqlQuery(‘SELECT * FROM Quote ORDER BY created DESC LIMIT 10′)
One word of caution, be careful with the name of the Bigtble table you enter, the query language is case sensitive. If you use lowercase quote as the table name in your query, you will get an exception “No implementation for kind ‘quote’.” Basically you can mix case for sql key words such as select and from but not the table name or column names.
Another issue that new Google App Engine developers will deal with involve indexes. On a deployed system, you need to define and build indexes used by your queries. You will get NeedIndexError errors if you do not have the same exact index you query for. Indexes are defined in index.yaml and this need to match the select query you execute in db.GqlQuery. If they do not match, such as you have an order by modified and created descending but query for created ascending then you will get this error.
A second issue I encountered with indexes is that they need to be built and this can take anywhere from a few minutes to hours. If the index is in the process of being built, you will still get the NeedIndexError. A framework is not a rapid development framework if once you deploy an application you have to sit on your ass for a day while it builds shit. This development environment reminds me of the programming model of 1950 when coders turned in piles of whole punched cards to an operator and had to return two days later for the result.
Because of my issues with indexes and other issues with settings I quickly learned that the production environment does not mirror the development environment as much as I would have hoped.
It seems that at the time of this writing, you can only set the authentication options at creation time. I wanted to have only users from my domain login as I developed the app and then switch to the world at a later time but because of this hard coded limitation, it seems I cannot do that.
This experience has thought me that learning a new platform requires learning a whole new set of known issues and limitations, and to discover new ones in the process. Anyone eager to deploy a web application on a new framework is a masochist.