Google App Engine 101: Learning To Deal With The App Engine

We believe in the power of knowledge sharing at Bright Creations.  One of the reasons behind this belief is that we use open source technologies and it allows us to effectively deliver through a collaborative community which always strives to contribute and offer the best it can provide.

That’s why we thought we’d give back to the community and share our experience using Google App Engine.

Before we start walking through some features of the app engine, we would like to thank our colleague Marawan Okasha for his astounding work on the app engine and his ongoing keenness to contribute.

As you all know Google App Engine is a cloud hosting environment created by Google where you can host your web applications.

Google App Engine’s – What you gain

Some of the benefits brought by Google app engine are:

  • No server administration is required.
  • Free Hosting up to a certain quota.
  • Pay for just the amount of resources you consume.
  • Automatic Scalability meaning the App Engine automatically adds new instances (servers) to your application when requests increase, it also assigns as much RAM and storage as your application requires and you can also configure a minimum or a maximum number of instances for your application.

Google App Engine’s Restrictions

Some of the essential restrictions which java applications deployed on Google App Engine need to abide by are:

  • java.awt.* package is not implemented so any user code using a class from this package will not work.
  • Writing files to the hard disk is not allowed (FileWriter, FileOutputStream) however App Engine does provide a File like API that simulates writing to a FileWriter which actually uses the blobstore behind the scenes.
  • No Relational DB is officially supported, so ORM libraries like Hibernate will not work; instead the App Engine provides a data structure called the Datastore which has no predefined schema and acts as a large Hashmap.
  • User code cannot create new threads however the App Engine SDK has other ways to create threads using Tasks, Backends and Scheduled Tasks.
  • Requests have a limit of 60 seconds to be completed or they will be interrupted by the App Engine and a 500 response will be sent back.

Google App Engine Features

The datastore and the blobstore are supported features by the app engine; you will find a brief explanation of each one as follows:

Data Store

The App engine does not support a traditional RDBMS; instead it works with its own data structure called the “Datastore”.

It provides replication, load-balancing services behind the scenes and has a stronger emphasis on read and querying performance than a traditional RDBM.

The storage mechanism is analogous to that of a Hashmap where you query the datastore with a key and it returns the value related.

You can also query on the properties of the object; however relationships between entities are not represented using foreign keys containing the id of the related entity as a substitute the “datastore” introduced a concept called the Key which encapsulates the id and the class of the entity it points to and acts as a foreign key.

A MySQL implementation is currently in limited release and expected to be released officially soon. The datastore has a JPA and JDO interface that can simplify the process of dealing with the low level datastore API.

Objectify

Although both JPA and JDO are standard Java data modeling interfaces yet they have a few restrictions when it comes to implementing them on the datastore; JPA for instance only supports Relational Databases and a lot of its features are built around the existence of a relational DBMS.

Hence, a large number of its features are disabled when it comes to modeling entities in the “datastore” using JPA particularly when it comes to querying which in JPA depends on the concept of foreign keys which is nonexistent in the datastore, a list of the unsupported features of JPA can be found here.

JDO is not RDBMS-specific, but it has a steep learning curve and moreover some of its features are not supported in the “datastore” environment.

A better and simpler approach than using the JPA or JDO interfaces, would be using the datastore-specific modeling framework Objectify. Objectify simplifies the process of fetching and writing data from/to the datastore. It uses the low-level Datastore API and a minimum number of annotations to make the four important datastore methods (get(), put(), delete(), or query()) simpler.

Example of a JDO Entity

@PersistenceCapable
public class Employee {
   @PrimaryKey
   @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
   private Key key;
   @Persistent
   private String firstName;
   @Persistent
   private String lastName;
}

Example of an Objectify Entity

class Car {
   @Id Long id;
   String firstName;
   String lastName;
}

Blobstore

The Blobstore is App Engine’s replacement for storing files in the filesystem, App Engine does not support writing file to the filesystem but offers an alternative in the Blobstore. The blobstore gives you the ability to store a large binary file and provides you with a “BlobKey” that you can use to retrieve the object later.

The standard way of interacting with the blobstore doesn’t involve you creating the blob directly; instead you call a blobstore method which generates a unique one-time URL used as an “action” for a form where the user can upload files.

                  blobstoreService.createUploadUrl(callbackUrl);

The App Engine takes care of storing the binary parameters in the POST data as blobs and redirects to a user-specified URL (callbackUrl) which has access to the blobkeys for these blobs.

                  Map<String, BlobKey> blobs = blobstoreService.getUploadedBlobs(request);

The servlet mapped to the callback URL cannot return an HTML response and must issue a redirect response to another URL.

A simpler but experimental way is by creating the blob yourself through an experimental API. You can use the Apache Commons File Upload API to gain access to the binary data of form fields.

Hope that’s useful.