Migrating to the Go 1.12+ runtime allows you to use up-to-date language features and build apps that are more portable, with idiomatic code.
Changes in the App Engine Go 1.12+ runtime
If you are considering a migration to the Go 1.12+ runtime, you should be aware of the following differences between Go 1.12+ and earlier runtimes on App Engine standard environment:
To reduce runtime migration effort and complexity, the App Engine standard environment allows you to access many of the legacy bundled services and APIs in the Go 1.12+ runtime, such as Memcache. Your Go 1.12+ app can call the bundled services APIs through the App Engine SDK for Go, and access most of the same functionality as on the Go 1.11 runtime.
You also have the option to use Google Cloud products that offer similar functionality as the legacy bundled services. These Google Cloud products provide idiomatic Cloud Client Libraries for Go. For the bundled services that are not available as separate products in Google Cloud, such as image processing, search, and messaging, you can use third-party providers or other workarounds.
To learn more about migrating to unbundled services, see Migrating from bundled services.
The behavior of some elements in the
app.yaml
configuration file has been modified. For more information, see Changes to theapp.yaml
file.Logging in the Go 1.12+ runtime follows the logging standard in Cloud Logging. In the Go 1.12+ runtime, app logs are no longer bundled with the request logs but are separated in different records. To learn more about reading and writing logs in the Go 1.12+ runtime, see the logging guide.
Changes to the app.yaml
file
The behavior of some elements in the app.yaml
configuration file has been
modified:
Element | Change type | Description |
---|---|---|
app_engine_apis |
Applicable to Go 1.12+ only | Must be set to true if you want to access the
legacy bundled services for Go 1.12+.
|
login |
Supported if app_engine_apis is true |
If you are not using the legacy bundled services for Go 1.12+, use these alternative methods to authenticate users. |
runtime |
Modified |
Change the runtime element to
specify Go 1.12+.
|
For more information, see the
app.yaml
reference.
Creating a main
package
Your service must include a package main
statement in at least one source
file. Alternatively, if your service is using the google.golang.org/appengine
package, include a call to appengine.Main()
.
Writing a main package
If your service doesn't already contain a main
package, add the
package main
statement and write a main()
function. At a minimum,
the main()
function should:
Read the
PORT
environment variable and call thehttp.ListenAndServe()
function:
Registering your HTTP handlers
You can register your HTTP handlers by choosing one of the following options:
- The preferred method is to manually move all
http.HandleFunc()
calls from your packages to yourmain()
function in yourmain
package. Alternatively, import your application's packages into your
main
package, ensuring eachinit()
function that contains calls tohttp.HandleFunc()
gets run on startup.You can find all packages which use the
http.HandleFunc()
call with the following bash script, and copy the output into yourmain
package'simport
block:gp=$(go env GOPATH) && p=$(pwd) && pkg=${p#"$gp/src/"} && find . -name "*.go" | xargs grep "http.HandleFunc" --files-with-matches | grep -v vendor/ | grep -v '/main.go' | sed "s#\./\(.*\)/[^/]\+\.go#\t_ \"$pkg/\1\"#" | sort | uniq
Structuring your files
Go requires each package has its own directory. You can tell
App Engine where your main
package is by using main:
in your
project's app.yaml
file. For example, if your app's file structure looked
like this:
myapp/ ├── app.yaml ├── foo.go ├── bar.go └── web/ └── main.go
Your app.yaml
file would have:
main: ./web # Relative filepath to the directory containing your main package.
For more information about the main
flag, see the app.yaml
reference.
Moving files to your GOPATH
Find your GOPATH
by using the following command:
go env GOPATH
Move all relevant files and imports to your GOPATH
. If using relative
imports, such as import ./guestbook
, update your imports to use the full
path: import github.com/example/myapp/guestbook
.