An entity is an instance of a data model, analogous to a data record of a database table.
When you store such a chunk of data, sometimes you need to locate it quickly, using a unique identifier. This is the entity's key.
Keys for data entities are typically unique relative to the data model. They are commonly hidden in a value in the program that manages and generates the web page, so that when the user clicks something, the appropriate key will be passed back to the server. This "passing of keys" (from the server, to the user, then back to the server) happens in any web application that empowers the user to create many-to-one relationships on a web page -- for example, to create a list with items.
The Google App Engine (GAE) hosting environment provides a database with a difference: when created, each entity is assigned a key that's universal to Google's "Big Table", guaranteed never to change, and guaranteed to be accessible only from your GAE application.
This implies an unusual approach to passing keys to the browser. When the webapp generates a web page the data choices can be hidden in the page, not with ID's generated on-the-fly, but with permanent, universal keys. There are clues on how to do this, mostly implied or embedded, scattered across the Google App Engine Group's discussion forum, the GAE cookbook, etc. But there are no simple, deployed examples. So I thought I would provide one.
Unfolding of an Example
To present this, I'm explicitly introducing an ancient illustrative technique to the world of software development, one that I think is particularly pleasant, unusually effective and full of future possibility: the unfolding of a program.
It's a polished sequence of steps in the development of a piece of software. This is rather different than a walk-through and explanation of finished code. You may have seen unfolding before in public programming performances ... in fact, Google introduced GAE with a well-rehearsed performance.
But one can go further with this idea.
For the moment, let's think of a program as a living organism. During an organism's development, its structure and shape changes, increasing in overall complexity through the application of simple changes, creating many intermediate and final layers. We marvel at nature's ability to maintain a coherent morphology amidst its vast engineering effort within a single living creature.
Amazingly, the elegant developmental sequences we see in nature, which generate such robust and complex mechanisms, are very flexible and adaptive. Living things tap a superb library of effective transformative solutions and methods. Since humans have only about 30,000 genes, life somehow creates robust, unique people from something analogous to 30,000 small functions. By comparison, the Linux Kernal needs over 10 million lines of code. We need to pay much closer attention to nature's methodology.
If you watch this gradual, incremental growth, you'll see difficult engineering problems overcome fluidly, simply, at each stage, at all scales. A great deal of ad hoc adaptation is going on, adaptations synthesized from available information, used in a persistent, beautiful, continuously balanced approach to tackling the emergence of the entire organism, and its critically important intermediate structures.
This holistic, incremental approach to growth can be seen as following, or borrowing from, many sequences of steps. Each step creates a simple morphological differentiation, applied globally, building upon the previous steps, providing the context for the next.
Surprisingly, although the number of sequences borrowed by a developing organism is vast, the number of differentiations is not. A human being develops in approximately 50 cell divisions, for example.
Assuming that programmers are called developers because they engage in something strongly akin to this kind of development, it's unfortunate that one of the least explored areas in programming is the study of the steps and sequences we use. When we decide to change code, at that moment, what are we doing? What are the problems, and what is our resolution? And where are we going? Clearly it would be useful to pass these steps and sequences around, among ourselves, for the sake of improving our discipline. The study of 'developmental programming' could provide a quicker, more efficient and effective absorption of new contexts, in the fast-changing world of engineering. Sequences could provide another tool for Open Source computer science. Unconsciously, we already organize our explanations in a kind of rough imitation of this process.
If all this talk seems redolent of Design Patterns, there's a reason. The notion to identify sequences of steps that humans should take, to build complex yet coherent and comprehensible systems, comes from Christopher Alexander, whose practical architectural philosophy inspired the computing movement to mine patterns and pattern languages. Research by Alexander and myself in the 1990's indicated, among many other things, that people take from a sequence whatever they need, absorbing information about dependencies, and borrowing solutions, and sensibilities, very like a developing organism making use of its genetic endowment.
I believe that polished sequences are a complement to patterns and refactoring ... after you've refactored towards various patterns, you tend to think: "if only I'd known about A! At this point I would have done A instead of B" or "Y turned into a huge time-wasting problem later on. I'm sure someone else has run into this."
Sequences give you the opportunity to save vast numbers of people from the frustration of poor solutions, and the expensive journey to rediscover an already known solution. Sequences can make us more effective, and help us to produce quality work more easily and more often.
So, to our example. I hope this new approach is useful, and that the sequence itself provides solutions large and small, from which you can borrow.