Retrieving An Entity By ID In Go

Here is a code snippet demonstrating how to retrieve a datastore entity by a known kind and integer ID. This code also retrieves the entity ID from a HTTP parameter.

R represents a http.Request reference. The entity ID to retrieve is accessed from the user’s submitted form under the name entity_idKind represents a string containing the name of the kind to retrieve from the datastore. The retrieved entity is stored into the variable entity, which is the struct CustomStruct.

c := appengine.NewContext(r)
//Retrieve the entity ID from the submitted form. Convert to an int64
entity_id := r.FormValue("entity_id")
entity_id_int, err := strconv.ParseInt(entity_id, 10, 64) 
if err != nil {
    fmt.Fprint(w, "Unable to parse key")
    return;
}
//We manufacture a datastore key based on the Kind and the 
//entity ID (passed to us via the HTTP request parameter.
key := datastore.NewKey(c, kind, "", entity_id_int, nil)
//Load the Entity this key represents.
//We have to state the variable first, then conduct the Get operation 
//so the datastore understands the struct representing the entity.
var entity CustomStruct
datastore.Get(c, key, &entity)

In short, this code pulls out the Entity ID from the HTTP request, converts it into an integer, manufactures the entity’s key using the kind and entity id, and then retrieves the corresponding entity. The code then translates the retrieved entity into the defined CustomStruct variable entity.

URL Path To Array In Golang

Here’s a short Go function that converts the URL path into an array; it’s useful if you want to implement REST style queries into a simple application.

func parseComponents(r *http.Request) []string {
    //Creates an App Engine Context - required to access App Engine specific services
    c := appengine.NewContext(r)
    //The URL that the user queried.
    path := r.URL.Path
    path = strings.TrimSpace(path)
    //Log the URL received:
    c.Infof("URL: ", path)
    //Cut off the leading and trailing forward slashes, if they exist.
    //This cuts off the leading forward slash.
    if strings.HasPrefix(path, "/") {
        path = path[1:]
    }
    //This cuts off the trailing forward slash.
    if strings.HasSuffix(path, "/") {
        cut_off_last_char_len := len(path) - 1
        path = path[:cut_off_last_char_len]
    }
    //We need to isolate the individual components of the path.
    components := strings.Split(path, "/")
    return components
}

HTTP Basic Access Authorization In Golang

One of the simplest and oldest methods of authorization is HTTP Basic authorization. While it isn’t as secure as the Users service of App Engine or the OAuth authorization model, it’s easy to implement and looks visually impressive depending on the user’s browser.

Here’s a picture of the HTTP Basic authorization prompt in IE10 on Windows 8:

The variable authorization contains a base64 encoded hash generated by the user’s browser, created by concatenating the username and password together with a colon: username:passwordR represents a http.Request reference, c is appengine.Context, and w is http.ResponseWriter.

//Get the authorization header.
authorization_array := r.Header["Authorization"]
if len(authorization_array) > 0 {
    authorization := strings.TrimSpace(authorization_array[0])
    c.Infof("Authorization: ", authorization)
} else {
    w.Header().Set("WWW-Authenticate", "Basic realm=\"user\"")
    http.Error(w, http.StatusText(401), 401)
}

Extract Subdomain From Request In Go

Here’s a code snippet that extracts the subdomain from an user’s request and places it as the first element in a new array.

R represents http.Request, and subdomain represents a new string array that has the extracted subdomain as its first and only element.

//The Host that the user queried.
host := r.URL.Host
host = strings.TrimSpace(host)
//Figure out if a subdomain exists in the host given.
host_parts := strings.Split(host, ".")
if len(host_parts) > 2 {
    //The subdomain exists, we store it as the first element 
    //in a new array
    subdomain := []string{host_parts[0]}
}

Configuring EdgeCache – A Cache For App Engine

App Engine has a distributed caching system called EdgeCache which can be configured to quickly serve static or rarely-changed assets. To tell EdgeCache to cache your files, you need to set the following two headers:

Cache-Control: public, max-age=[time in seconds to cache]
Pragma: Public

The max-age argument takes the number of seconds to cache the given file. It must be set to at least 61 seconds.

Here’s example Java code to implement these headers. The max age is set to 86,400 seconds (1 day). The resp object represents a HttpServletResponse class:

resp.setHeader("Cache-Control", "public, max-age=86400");
resp.setHeader("Pragma", "Public");

Here’s the same code implemented in Go ( w represents http.ResponseWriter ):

w.Header().Set("Cache-Control", "public, max-age=86400")
w.Header().Set("Pragma", "Public")

Storing To The Memcache In Golang

A short Golang example: how to store to memcache in Go. To use this, you’ll need to import appengine/memcache.

This code fragment generates a memcache.Item struct, to which you’ll need to supply a key and the value you want stored (a struct, array, map, etc).

memcache_item := &memcache.Item {
    Key: "key_to_this_object",
    Object: item_to_store,
}

//Store into Memcache
memcache.JSON.Set(c, memcache_item)

A Simple index.yaml File

The App Engine SDK developer server can automatically create datastore indexes for your application – just run the datastore querying code within the dev server. But sometimes that isn’t possible.

In that case, you can hand-write your index settings. Here is an example of a simple index.yaml file. It indexes all entities with a kind of Fact, on the property Approved and sorts on the property Add_date in descending order.

indexes:

- kind: Fact
  ancestor: no
  properties:
  - name: Approved
  - name: Add_date
    direction: desc

index.yaml goes in the root directory of your application.

Sending Mail With Golang

Previously I published a Java code example using the low level Mail API to send a message to the registered admins of an application. Here’s sample code for a Golang application to send mail to app admins. C stands for an appengine.Context reference.

If you want to send mail to an arbitrary user, and not an admin, you can uncomment the To line and change SendToAdmins() to Send().

application_id := appengine.AppID(c)
separation_point := strings.Index(application_id, ":")
if separation_point > -1 {
    application_id = application_id[separation_point:]
}

//Create the message struct
msg := &mail.Message{
    Sender:  "donotreply@" + application_id + ".appspotmail.com",
    //To:    []string{"To-User <[email protected]>"},
    Subject: subject,
    Body:    email_body,
}
c.Infof("Sending message: %v", msg)

//Send an email to admins
err := mail.SendToAdmins(c, msg)
if err != nil {
    c.Errorf("Unable to send email: %v", err)
}

Mapping Favicon.ico In A Golang Application

One of the most annoying issues about configuring a Go based app is correctly mapping every file to its proper path.

For instance, beginners at Go frequently declare their first handler like so:

http.HandleFunc("/", handler)

And declare a simple app.yaml, similar to the one below:

application: application_id
version: 1
runtime: go
api_version: go1

handlers:
- url: /.*
  script: _go_app

Unfortunately this will cause all requests to be routed to your Go application code, even if you have static files in your application’s root directory.

To map favicon.ico (or any static file in the app’s root directory) so AppEngine will serve it, replace the handlers section in app.yaml to properly indicate where it is and the url it maps to:

handlers:
- url: /favicon\.ico
  static_files: favicon.ico
  upload: favicon\.ico
- url: /.*
  script: _go_app

Golang Error: not enough arguments to return

One of the strengths of Go is the ability to return multiple values from a function. As a long-time Java programmer I’ve envied languages with muttiple returns for a long time. Here’s a quick summary of the feature:

Quick example: to return multiple values, use the classic return statement:

 return value1, value2

And to get those return values from a function, you can write:

 var1, var2 := someMultipleReturnFunction()

The great thing about this system is that you can ignore a return value if you don’t need it. For example, if you need to skip the first return value:

 _, var2 := someMultipleReturnFunction()

Which brings me to the original reason for this blog post. I was writing a Go application, when a build failed due to the error not enough arguments to return. The problem was that I had multiple return statements within a function, and one of the statements declared only one return value, instead of the two return values that the function declared.

The easy fix? Simply declare nil to pad out the “missing” return value. So the return statement became:

 return var1, nil

Easy, quick, and painless.