透過 Remote API 存取 App Engine

Google Cloud CLI 包含 remote_api 套件,可讓您用清楚明瞭的方式從任何 Go 應用程式存取 App Engine 服務。舉例來說,您可以透過 Remote API,從在本機電腦上執行的應用程式,或從其他 App Engine 應用程式存取 Datastore。

如要查看 remote_api 套件的內容,請參閱 remote_api 套件參考資料。

啟用 Remote API

首先,將 remote_api url 處理常式新增至 app.yaml。例如:

- url: /_ah/remote_api
  script: _go_app

這會將網址 /_ah/remote_api 對應至 Go 應用程式。遠端 API 處理常式會限制只有應用程式管理員可以存取這個網址。

接著,在專案的其中一個套件中匯入 remote_api 套件,方法是在任一 .go 來源檔案中加入下列程式碼:

import _ "google.golang.org/appengine/remote_api"

在程式初始化過程中,remote_api 套件會為處理常式註冊 /_ah/remote_api 路徑。匯入宣告中的底線意指「匯入此套件,但不直接使用該套件。」若無底線,您會在編譯時收到「已匯入但未使用」錯誤訊息。

最後,請將更新部署至 App Engine。例如:

gcloud app deploy app.yaml

在本機用戶端上使用 Remote API

Remote API 可以用來編寫使用 App Engine 服務並存取資料儲存庫的本機應用程式。請注意,使用 Remote API 將會對您正在存取的應用程式產生配額使用費用。

開始之前,請務必在 App Engine 應用程式中啟用 Remote API。本機應用程式可以建立 remote_api.NewRemoteContext,並使用該內容來替代所有 API 呼叫中的正常 App Engine 內容,藉此使用 Remote API。

// 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.

package main

import (
	"log"
	"time"

	"golang.org/x/net/context"
	"golang.org/x/oauth2/google"

	"google.golang.org/appengine/datastore"
	"google.golang.org/appengine/remote_api"
)

func main() {
	const host = "<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",
	)
	if err != nil {
		log.Fatal(err)
	}

	remoteCtx, err := remote_api.NewRemoteContext(host, hc)
	if err != nil {
		log.Fatal(err)
	}

	q := datastore.NewQuery("Greeting").
		Filter("Date >=", time.Now().AddDate(0, 0, -7))

	log.Println(q.Count(remoteCtx))
}

如要執行此程式碼,您需要擷取以下套件:

$ go get google.golang.org/appengine/...
$ go get golang.org/x/oauth2/...

您需要提供伺服器的主機名稱,並在呼叫 NewRemoteContext 時提供 http.Client。提供的 http.Client 負責傳送每個要求中的必要驗證資訊。

在以上範例中,DefaultClient 套件中的 golang.org/x/oauth2/google 透過應用程式預設憑證提供 OAuth 2 憑證。

限制與最佳做法

remote_api 模組會盡所有可能,使其運作方式與原生 App Engine 資料儲存庫完全相同。在某些情況下,這意謂著該運作效率可能會較原有運作方式低。使用 remote_api 時,必須記住幾個重點:

每個資料儲存庫要求都需要一去一回

由於您是透過 HTTP 存取資料儲存庫,因此產生的負擔與延遲會比本機存取略高一些。為加快速度並減少負荷,請透過批次取得與放入,以及批次從查詢擷取實體,嘗試限制去回的次數。無論對於 remote_api,還是在一般情況下使用資料儲存庫,這都是非常好的建議,因為系統只會將批次作業視為單一資料儲存庫作業。

向 remote_api 發出的要求會使用配額

由於 remote_api 透過 HTTP 操作,因此您每次呼叫資料儲存庫都會針對 HTTP 要求產生配額使用量、接收和傳送的位元組,以及您預期的一般資料儲存庫配額。如果您是透過 remote_api 執行批次更新,請務必記住這一點。

適用 1 MB API 限制

跟在本機執行時一樣,API 要求和回應的 1MB 限制仍然適用。如果您的實體數量特別龐大,您可能需要限制一次擷取或放入的數量,以符合這個限制。不幸的是,這會與去回次數的最小化發生衝突,因此最好的做法是,使用不超過要求或回應限制的最大批次操作數量。但是,就大多數的實體來說,這不會是一個問題。

避免疊代處理查詢

疊代處理查詢時,SDK 會從資料儲存庫中擷取 20 個批次的實體,並在用完現有批次時擷取新的批次。因為 remote_api 必須透過個別要求擷取每批實體,所以效率很低。因此,remote_api 改為使用偏移功能深入結果,為每個批次執行全新的查詢。

如果您知道您需要的實體數量,您可以要求所需數量,即可透過單一要求完成整個擷取。

如果您不知道需要多少實體,則可以使用游標有效地疊代處理大型結果集。這也可以讓您規避一般資料儲存庫查詢的 1000 個實體限制。

交易的效率較低

為了透過 remote_api 實作交易,將累積在交易內部擷取的實體資訊,以及在交易內部放置或刪除的實體副本。認可交易之後,系統會將這些資訊全數傳送至 App Engine 伺服器,而其必須在此處再次擷取交易所使用的所有實體、確認這些實體未遭到修改,然後放入並刪除交易所做的所有變更,再予以認可。如果發生衝突,伺服器會退回交易,並通知用戶端,然後用戶端必須重複整個過程。

這個方法是行得通的,而且會在本機資料儲存庫上完整重現交易所提供的功能,不過效率較低。總而言之,您可以在需要時使用交易,但是為求效率,請嘗試限制您執行的交易數量與複雜性。