什么是GO适当的方式来创建一个FetchUrl/GetURL函数从命令行工作,并从谷歌应用程序引擎以其自定义的方式来获取URL的作品。跨平台代码为appengine
我有基本的代码,获取和处理一些URL上的数据。我希望能够从我在桌面上使用的代码调用它,并将代码部署到应用程序引擎。
希望多数民众赞成清楚,如果没有请让我知道和病态澄清。
什么是GO适当的方式来创建一个FetchUrl/GetURL函数从命令行工作,并从谷歌应用程序引擎以其自定义的方式来获取URL的作品。跨平台代码为appengine
我有基本的代码,获取和处理一些URL上的数据。我希望能够从我在桌面上使用的代码调用它,并将代码部署到应用程序引擎。
希望多数民众赞成清楚,如果没有请让我知道和病态澄清。
如果你有一些代码可以在本地机器和AppEngine环境中工作,那你就什么都不做。
如果您需要在AppEngine上做或应该做不同的事情,那么您需要检测环境并为不同的环境编写不同的代码。
使用build constraints可以轻松完成此检测和代码选择。您可以在.go
文件的开头放置一条特殊注释行,根据环境的不同,它可能也可能不会被编译和运行。
从The Go Blog: The App Engine SDK and workspaces (GOPATH)报价:
App Engine的SDK引入了一种新的构建约束项:
"appengine"
。指定的文件将由App Engine SDK构建,并由go工具忽略。相反,指定的文件
// +build !appengine
会被App Engine SDK忽略,而go工具会很乐意构建它们。
因此,例如,您可以有两个单独的.go
文件,一个用于AppEngine,一个用于本地(非AppEngine)环境。在两者中定义相同的函数(使用相同的参数列表),因此无论代码在哪个环境中构建,函数都会有一个声明。我们将使用这个签名:
func GetURL(url string, r *http.Request) ([]byte, error)
注意,第二个参数(*http.Request
)只需要在AppEngine上(为了能够创建一个Context
),所以在当地ENV的实现不使用它(甚至可以是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
}
您可以在golang/appengine
项目本身中获得一些线索。
例如,其remote_api/client.go
提供客户端远程连接到用户的生产应用程序。
你去通过包括这些例子来回答这个问题。我不知道使用''+ build''的能力。非常感谢。 – Jacob