Learn how to migrate your existing App Engine app from the Go 1.9 runtime to the Go 1.12+ runtimes of the App Engine standard environment.
Changes in the App Engine Go 1.12+ runtimes
You must make changes to your existing App Engine Go app and your deployment process in order to use the App Engine Go 1.12+ runtimes. The key differences in the new runtimes are outlined below:
You specify the Go 1.12 or 1.13 runtime in your
app.yaml
file by using the lineruntime: go112
orruntime: go113
. For more information, see Changes to theapp.yaml
file.The Go 1.12+ runtimes do not provide access to proprietary App Engine APIs. You can use the Google Cloud client library or third party libraries to access Google Cloud services. You can find suggested alternatives to App Engine APIs in the Migrating from the App Engine Go SDK section.
Each of your services must include a
main
package. For more information, see Creating amain
package and Structuring your files.The
appengine
build tag is deprecated and will not be used when building your app for deployment.How you import dependencies into your project has changed. For the Go 1.12+ runtimes, specify dependencies either by:
- Putting your application and related code in your
GOPATH
. - Or, creating a
go.mod
file to define your module.
For more information, see Specifying dependencies.
- Putting your application and related code in your
App Engine no longer modifies the Go toolchain to include the
appengine
package. If you are using theappengine
package or thegoogle.golang.org/appengine
package, you must migrate to the Google Cloud client library.You must use the
gcloud app deploy
command to deploy your app, services, and configuration files, such as thequeue.yaml
andcron.yaml
files.
Migrating from the App Engine Go SDK
The appengine
package and the google.golang.org/appengine
package are no
longer supported. You will have to migrate to the
Google Cloud client library to access
equivalent Google Cloud services:
- Use Cloud Tasks to enqueue tasks
from Go 1.12 and newer using the
cloudtasks
package. You can use any App Engine service as the target of an App Engine task. - Instead of the App Engine Mail API, use a third-party mail provider such as SendGrid, Mailgun, or Mailjet to send email. All of these services offer APIs to send email from applications.
- To use a memcache service on App Engine, use Redis Labs Memcached Cloud instead of App Engine Memcache.
Access the App Engine Modules API using the
google-api-go-client
library. Use the environment variables and the App Engine Admin API to obtain information and modify your application's running services:Service information How to access Current service name GAE_SERVICE
environment variableCurrent service version GAE_VERSION
environment variableCurrent instance ID GAE_INSTANCE
environment variableDefault hostname Admin API apps.get
methodList of services Admin API apps.services.list
methodList of versions for a service Admin API apps.services.versions.list
methodDefault version for a service, including any traffic splits Admin API apps.services.get
methodList of running instances for a version Admin API apps.services.versions.instances.list
methodCloud Storage is recommended over using the App Engine Blobstore API. Use Cloud Storage through the
storage
package. To get started, see the Cloud Storage Client Libraries page.Access Datastore through the
datastore
package. To get started, see the Datastore Client Libraries page.Instead of using the App Engine Search API, host any full-text search database such as ElasticSearch on Compute Engine and access it from your service.
Use similar functionalities provided by the App Engine Images API in Cloud Storage through the
storage
package and a third-party service to manipulate images. To get started, see the Cloud Storage Client Libraries page.Use
request.Context()
or your preferred context instead of usingappengine.NewContext
.The following App Engine-specific functionalities have been superseded by the Go standard library packages listed below:
App Engine package Go standard library package cloudsql
packagedatabase/sql
packagefile
packageos
packagelog
packagelog
packagesocket
packagenet
packageurlfetch
packagenet/http
package
Changes to the app.yaml
file
The behavior of some elements in the app.yaml
configuration file has been
modified:
Element | Change type | Description |
---|---|---|
api_version |
Deprecated | |
runtime |
Modified |
Change the runtime element to specify
runtime: go112 or runtime: go113
|
application_readable |
Deprecated | |
builtins |
Deprecated | |
includes |
Deprecated | |
login |
Deprecated |
The Go 1.12+ runtimes do not support login . You must use
alternative methods to authenticate users.
|
libraries |
Deprecated | |
threadsafe |
Deprecated | All applications are presumed to be threadsafe, meaning an instance can handle multiple requests at the same time. |
skip_files |
Deprecated |
Instead create a .gcloudignore file in the root directory
where your app.yaml file is located. For more information,
see the
.gcloudignore reference.
|
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.
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:
runtime: go113 # or go112 for the Go 1.12 runtime
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
.