gpt4 book ai didi

google-app-engine - Appengine 的跨平台 Go 代码

转载 作者:IT王子 更新时间:2023-10-29 01:42:06 27 4
gpt4 key购买 nike

创建 FetchUrl/GetURL 函数的 GO 合适方法是什么,该函数可以从命令行运行,也可以从谷歌应用引擎运行,并使用其自定义方式来获取 url。

我有基本代码可以获取和处理 URL 上的一些数据。我希望能够从我在桌面上使用的代码以及部署到 App Engine 的代码中调用它。

希望这很清楚,如果没有请告诉我,我会澄清。

最佳答案

如果您有一些代码既可以在本地机器上运行,也可以在 AppEngine 环境上运行,那么您无事可做。

如果您需要做一些应该或必须在 AppEngine 上以不同方式完成的事情,那么您需要检测环境并为不同的环境编写不同的代码。

这种检测和代码选择最容易使用 build constraints 完成.您可以在.go 文件的开头放置一个特殊的注释行,它可能会或可能不会编译和运行,具体取决于环境。

引自The Go Blog: The App Engine SDK and workspaces (GOPATH) :

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.

例如,您可以有 2 个单独的 .go 文件,一个用于 AppEngine,一个用于本地(非 AppEngine)环境。在两者中定义相同的函数(具有相同的参数列表),因此无论代码在哪个环境中构建,函数都将有一个声明。我们将使用这个签名:

func GetURL(url string, r *http.Request) ([]byte, error)

请注意,第二个参数 (*http.Request) 只有 AppEngine 需要(以便能够创建 Context),因此在实现中对于本地环境,它不被使用(甚至可以是 nil)。

优雅的解决方案可以利用 http.Client类型在标准环境和 AppEngine 中均可用,可用于执行 HTTP GET 请求。 http.Client 值可以在 AppEngine 上以不同的方式获取,但是一旦我们有了 http.Client 值,我们就可以以相同的方式进行。所以我们将有一个通用代码,它接收一个 http.Client 并可以完成其余的工作。

示例实现如下所示:

url_local.go:

// +build !appengine

package mypackage

import (
"net/http"
)

func GetURL(url string, r *http.Request) ([]byte, error) {
// Local GetURL implementation
return GetClient(url, &http.Client{})
}

url_gae.go:

// +build appengine

package mypackage

import (
"google.golang.org/appengine"
"google.golang.org/appengine/urlfetch"
"net/http"
)

func GetURL(url string, r *http.Request) ([]byte, error) {
// Appengine GetURL implementation
ctx := appengine.NewContext(r)
c := urlfetch.Client(ctx)
return GetClient(url, c)
}

url_common.go:

// No build constraint: this is common code

package mypackage

import (
"net/http"
)

func GetClient(url string, c *http.Client) ([]byte, error) {
// Implementation for both local and AppEngine
resp, err := c.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return body, nil
}

关于google-app-engine - Appengine 的跨平台 Go 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37762384/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com