# The App Engine SDK and workspaces (GOPATH)
9 Jan 2013
Tags: appengine, tools, gopath
Summary: App Engine SDK 1.7.4 adds support for GOPATH-style workspaces.
OldURL: /the-app-engine-sdk-and-workspaces-gopath

Andrew Gerrand

## Introduction

When we released Go 1 we introduced the [go tool](https://golang.org/cmd/go/) and,
with it, the concept of workspaces.
Workspaces (specified by the GOPATH environment variable) are a convention
for organizing code that simplifies fetching,
building, and installing Go packages.
If you're not familiar with workspaces, please read [this article](https://golang.org/doc/code.html)
or watch [this screencast](http://www.youtube.com/watch?v=XCsL89YtqCs) before reading on.

Until recently, the tools in the App Engine SDK were not aware of workspaces.
Without workspaces the "[go get](https://golang.org/cmd/go/#hdr-Download_and_install_packages_and_dependencies)"
command cannot function,
and so app authors had to install and update their app dependencies manually. It was a pain.

This has all changed with version 1.7.4 of the App Engine SDK.
The [dev\_appserver](https://developers.google.com/appengine/docs/go/tools/devserver)
and [appcfg](https://developers.google.com/appengine/docs/go/tools/uploadinganapp)
tools are now workspace-aware.
When running locally or uploading an app,
these tools now search for dependencies in the workspaces specified by the
GOPATH environment variable.
This means you can now use "go get" while building App Engine apps,
and switch between normal Go programs and App Engine apps without changing
your environment or habits.

For example, let's say you want to build an app that uses OAuth 2.0 to authenticate
with a remote service.
A popular OAuth 2.0 library for Go is the [oauth2](https://godoc.org/golang.org/x/oauth2) package,
which you can install to your workspace with this command:

	go get golang.org/x/oauth2

When writing your App Engine app, import the oauth package just as you would in a regular Go program:

	import "golang.org/x/oauth2"

Now, whether running your app with the dev\_appserver or deploying it with appcfg,
the tools will find the oauth package in your workspace. It just works.

## Hybrid stand-alone/App Engine apps

The Go App Engine SDK builds on Go's standard [net/http](https://golang.org/pkg/net/http/)
package to serve web requests and,
as a result, many Go web servers can be run on App Engine with only a few changes.
For example, [godoc](https://golang.org/cmd/godoc/) is included in the
Go distribution as a stand-alone program,
but it can also run as an App Engine app (godoc serves [golang.org](https://golang.org/) from App Engine).

But wouldn't it be nice if you could write a program that is both a stand-alone
web server and an App Engine app? By using [build constraints](https://golang.org/pkg/go/build/#hdr-Build_Constraints), you can.

Build constraints are line comments that determine whether a file should
be included in a package.
They are most often used in code that handles a variety of operating systems
or processor architectures.
For instance, the [path/filepath](https://golang.org/pkg/path/filepath/)
package includes the file [symlink.go](https://golang.org/src/pkg/path/filepath/symlink.go),
which specifies a build constraint to ensure that it is not built on Windows
systems (which do not have symbolic links):

	// +build !windows

The App Engine SDK introduces a new build constraint term: "appengine". Files that specify

	// +build appengine

will be built by the App Engine SDK and ignored by the go tool. Conversely, files that specify

	// +build !appengine

are ignored by the App Engine SDK, while the go tool will happily build them.

The [goprotobuf](http://code.google.com/p/goprotobuf/) library uses this
mechanism to provide two implementations of a key part of its encode/decode machinery:
[pointer\_unsafe.go](http://code.google.com/p/goprotobuf/source/browse/proto/pointer_unsafe.go)
is the faster version that cannot be used on App Engine because it uses
the [unsafe package](https://golang.org/pkg/unsafe/),
while [pointer\_reflect.go](http://code.google.com/p/goprotobuf/source/browse/proto/pointer_reflect.go)
is a slower version that avoids unsafe by using the [reflect package](https://golang.org/pkg/reflect/) instead.

Let's take a simple Go web server and turn it into a hybrid app. This is main.go:

	package main

	import (
	    "fmt"
	    "net/http"
	)

	func main() {
	    http.HandleFunc("/", handler)
	    http.ListenAndServe("localhost:8080", nil)
	}

	func handler(w http.ResponseWriter, r *http.Request) {
	    fmt.Fprint(w, "Hello!")
	}

Build this with the go tool and you'll get a stand-alone web server executable.

The App Engine infrastructure provides its own main function that runs its
equivalent to ListenAndServe.
To convert main.go to an App Engine app, drop the call to ListenAndServe
and register the handler in an init function (which runs before main). This is app.go:

	package main

	import (
	    "fmt"
	    "net/http"
	)

	func init() {
	    http.HandleFunc("/", handler)
	}

	func handler(w http.ResponseWriter, r *http.Request) {
	    fmt.Fprint(w, "Hello!")
	}

To make this a hybrid app, we need to split it into an App Engine-specific part,
an stand-alone binary-specific part, and the parts common to both versions.
In this case, there is no App Engine-specific part,
so we split it into just two files:

app.go specifies and registers the handler function.
It is identical to the code listing above,
and requires no build constraints as it should be included in all versions of the program.

main.go runs the web server. It includes the "!appengine" build constraint,
as it must only included when building the stand-alone binary.

	// +build !appengine

	package main

	import "net/http"

	func main() {
	    http.ListenAndServe("localhost:8080", nil)
	}

To see a more complex hybrid app, take a look at the [present tool](https://godoc.org/golang.org/x/tools/present).

## Conclusions

We hope these changes will make it easier to work on apps with external dependencies,
and to maintain code bases that contain both stand-alone programs and App Engine apps.
