// Copyright 2011 Google Inc. All rights reserved.// Use of this source code is governed by the Apache 2.0// license that can be found in the LICENSE file.packagemainimport("log""time""golang.org/x/net/context""golang.org/x/oauth2/google""google.golang.org/appengine/datastore""google.golang.org/appengine/remote_api")funcmain(){consthost="<your-app-id>.appspot.com"ctx:=context.Background()hc,err:=google.DefaultClient(ctx,"https://www.googleapis.com/auth/appengine.apis","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/cloud-platform",)iferr!=nil{log.Fatal(err)}remoteCtx,err:=remote_api.NewRemoteContext(host,hc)iferr!=nil{log.Fatal(err)}q:=datastore.NewQuery("Greeting").Filter("Date >=",time.Now().AddDate(0,0,-7))log.Println(q.Count(remoteCtx))}
[[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["很难理解","hardToUnderstand","thumb-down"],["信息或示例代码不正确","incorrectInformationOrSampleCode","thumb-down"],["没有我需要的信息/示例","missingTheInformationSamplesINeed","thumb-down"],["翻译问题","translationIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2025-09-04。"],[[["\u003cp\u003eThe Google Cloud CLI's \u003ccode\u003eremote_api\u003c/code\u003e package allows Go applications to access App Engine services, including Datastore, from outside of the App Engine environment, such as a local machine.\u003c/p\u003e\n"],["\u003cp\u003eEnabling the Remote API requires adding a \u003ccode\u003eurl\u003c/code\u003e handler to your \u003ccode\u003eapp.yaml\u003c/code\u003e file and importing the \u003ccode\u003eremote_api\u003c/code\u003e package into your Go project, with specific attention to using the underscore import notation.\u003c/p\u003e\n"],["\u003cp\u003eLocal applications can interact with App Engine services by creating a context with \u003ccode\u003eremote_api.NewRemoteContext\u003c/code\u003e and utilizing it instead of the regular App Engine context in API calls, with the necessary credentials provided through an \u003ccode\u003ehttp.Client\u003c/code\u003e.\u003c/p\u003e\n"],["\u003cp\u003eUsing the \u003ccode\u003eremote_api\u003c/code\u003e package involves certain considerations, such as increased latency due to HTTP round-trips, quota usage for every Datastore call, and the 1MB API request/response limits, which may require batching of operations.\u003c/p\u003e\n"],["\u003cp\u003eWhen querying data, it's recommended to avoid iterating over queries due to inefficiency and use cursors for large result sets, and while transactions are supported, they are less efficient and should be used sparingly.\u003c/p\u003e\n"]]],[],null,["# Accessing App Engine with Remote API\n\nThe Google Cloud CLI includes a `remote_api` package that lets you transparently\naccess App Engine services from any Go application. For example, you can use the\nRemote API to access Datastore from an app running on your local\nmachine or from another one of your App Engine apps.\n\nTo view the contents of the `remote_api` package, see the\n[`remote_api` package](/appengine/docs/legacy/standard/go111/tools/remoteapi/reference)\nreference.\n| **Caution:** **This solution is no longer recommended:** Apps that use this API can only run in the Go 1.11 runtime and will need to upgrade to a [recommended solution](/appengine/migration-center/standard/services/migrating-services) before migrating to the Go 1.12+ runtime.\n\nEnabling Remote API\n-------------------\n\nFirst, add the `remote_api` `url` handler to your `app.yaml`. For example: \n\n - url: /_ah/remote_api\n script: _go_app\n\nThis maps the URL `/_ah/remote_api` to your Go app. Access to this URL is\nrestricted to administrators for the application by the Remote API handler.\n\nThen you import the `remote_api` package in one of your project's\npackages by adding the following line to any of your `.go` source files: \n\n import _ \"google.golang.org/appengine/remote_api\"\n\nDuring program initialization, the `remote_api` package registers a handler\nfor the `/_ah/remote_api` path. The underscore in the import\ndeclaration means \"import this package, but we won't use it directly.\" Without\nthe underscore, you would receive an \"imported but not used\" error message on\ncompilation.\n\nFinally, you [deploy the update to\nApp Engine](/appengine/docs/legacy/standard/go111/tools/uploadinganapp). For example: \n\n gcloud app deploy app.yaml\n\nUsing the Remote API in a Local Client\n--------------------------------------\n\nThe Remote API can be used to write local applications that use App Engine\nservices and access datastore. It is important to note that using the Remote\nAPI will incur quota usage on the application you are accessing.\n\nBefore beginning, make sure the Remote API is enabled in your App Engine\napplication. The local application can use the Remote API by creating a context\nwith `remote_api.NewRemoteContext`, and using that in place of the regular App\nEngine context in all API calls. \n\n // Copyright 2011 Google Inc. All rights reserved.\n // Use of this source code is governed by the Apache 2.0\n // license that can be found in the LICENSE file.\n\n package main\n\n import (\n \t\"log\"\n \t\"time\"\n\n \t\"golang.org/x/net/context\"\n \t\"golang.org/x/oauth2/google\"\n\n \t\"google.golang.org/appengine/datastore\"\n \t\"google.golang.org/appengine/remote_api\"\n )\n\n func main() {\n \tconst host = \"\u003cyour-app-id\u003e.appspot.com\"\n\n \tctx := context.Background()\n\n \thc, err := google.DefaultClient(ctx,\n \t\t\"https://www.googleapis.com/auth/appengine.apis\",\n \t\t\"https://www.googleapis.com/auth/userinfo.email\",\n \t\t\"https://www.googleapis.com/auth/cloud-platform\",\n \t)\n \tif err != nil {\n \t\tlog.Fatal(err)\n \t}\n\n \tremoteCtx, err := remote_api.https://cloud.google.com/appengine/docs/legacy/standard/go111/reference/latest/remote_api.html#google_golang_org_appengine_remote_api_NewRemoteContext(host, hc)\n \tif err != nil {\n \t\tlog.Fatal(err)\n \t}\n\n \tq := datastore.https://cloud.google.com/appengine/docs/legacy/standard/go111/reference/latest/datastore.html#google_golang_org_appengine_datastore_Query_NewQuery(\"Greeting\").\n \t\thttps://cloud.google.com/appengine/docs/legacy/standard/go111/reference/latest/datastore.html#google_golang_org_appengine_datastore_Query_Filter(\"Date \u003e=\", time.Now().AddDate(0, 0, -7))\n\n \tlog.Println(q.https://cloud.google.com/appengine/docs/legacy/standard/go111/reference/latest/datastore.html#google_golang_org_appengine_datastore_Query_Count(remoteCtx))\n }\n\nTo run this code, you need to fetch these packages: \n\n $ go get google.golang.org/appengine/...\n $ go get golang.org/x/oauth2/...\n\nYou need to provide the hostname of your server and a `http.Client` in the call\nto `NewRemoteContext`. The provided `http.Client` is responsible for passing\nthe required authentication information in each request.\n\nIn the sample above, the `DefaultClient` from the `golang.org/x/oauth2/google`\npackage provides OAuth 2 credentials via [Application Default Credentials](https://developers.google.com/identity/protocols/application-default-credentials).\n\nLimitations and best practices\n------------------------------\n\nThe remote_api module goes to great lengths to make sure that as far as\npossible, it behaves exactly like the native App Engine datastore. In some\ncases, this means doing things that are less efficient than they might\notherwise be. When using remote_api, here's a few things to keep in mind:\n\n### Every datastore request requires a round-trip\n\nBecause you're accessing the datastore over HTTP, there's a bit more overhead\nand latency than when you access it locally. In order to speed things up and\ndecrease load, try to limit the number of round-trips you do by batching\ngets and puts, and fetching batches of entities from queries. This is good\nadvice not just for remote_api, but for using the datastore in general,\nbecause a batch operation is only considered to be a single Datastore\noperation.\n\n### Requests to remote_api use quota\n\nBecause the remote_api operates over HTTP, every datastore call you make incurs\nquota usage for HTTP requests, bytes in and out, as well as the usual\ndatastore quota you would expect. Bear this in mind if you're using\nremote_api to do bulk updates.\n\n### 1 MB API limits apply\n\nAs when running natively, the 1MB limit on API requests and responses still\napplies. If your entities are particularly large, you may need to limit the\nnumber you fetch or put at a time to keep below this limit. This conflicts\nwith minimising round-trips, unfortunately, so the best advice is to use the\nlargest batches you can without going over the request or response size\nlimitations. For most entities, this is unlikely to be an issue, however.\n\n### Avoid iterating over queries\n\nWhen you iterate over queries, the SDK fetches entities from the datastore in\nbatches of 20, fetching a new batch whenever it uses up the existing ones.\nBecause each batch has to be fetched in a separate request by remote_api, it's\nunable to do this as efficiently. Instead, remote_api executes an entirely new\nquery for each batch, using the offset functionality to get further into the\nresults.\n\nIf you know how many entities you need, you can do the whole fetch in one\nrequest by asking for the number you need.\n\nIf you don't know how many entities you will want, you can use\n[cursors](/appengine/docs/legacy/standard/go111/datastore/query-cursors)\nto efficiently iterate over large result sets. This also\nallows you to avoid the 1000 entity limit imposed on normal datastore\nqueries.\n\n### Transactions are less efficient\n\nIn order to implement transactions via remote_api, it accumulates\ninformation on entities fetched inside the transaction, along with copies of\nentities that were put or deleted inside the transaction. When the\ntransaction is committed, it sends all of this information off to the App\nEngine server, where it has to fetch all the entities that were used in the\ntransaction again, verify that they have not been modified, then put and\ndelete all the changes the transaction made and commit it. If\nthere's a conflict, the server rolls back the transaction and notifies the\nclient end, which then has to repeat the process all over again.\n\nThis approach works, and exactly duplicates the functionality provided by\ntransactions on the local datastore, but is rather inefficient. By all means\nuse transactions where they are necessary, but try to limit the number and\ncomplexity of the transactions you execute in the interest of efficiency."]]