创建FetchUrl / GetURL函数的GO适当方法是什么?该函数可以从命令行运行,并且可以通过谷歌应用引擎以自定义方式获取网址。
我有基本代码来获取和处理URL上的一些数据。我希望能够从我在桌面上使用的代码中调用它,并将代码部署到app引擎。
希望这清楚,如果不是,请让我知道并且我要澄清。
答案 0 :(得分:2)
如果您的某些代码在本地计算机和AppEngine环境中都有效,则无需执行任何操作。
如果你需要做一些应该或必须在AppEngine上做不同的事情,那么你需要检测环境并为不同的环境编写不同的代码。
使用build constraints最简单地完成此检测和代码选择。您可以在.go
文件的开头添加一个特殊注释行,它可能会也可能不会根据环境进行编译和运行。
引自The Go Blog: The App Engine SDK and workspaces (GOPATH):
App Engine SDK引入了新的构建约束术语:
的文件"appengine"
。指定// +build appengine
将由App Engine SDK构建,并由go工具忽略。相反,指定
的文件App Engine SDK会忽略// +build !appengine
,而go工具会很乐意构建它们。
例如,您可以拥有2个单独的.go
文件,一个用于AppEngine,另一个用于本地(非AppEngine)环境。在两者中定义相同的函数(使用相同的参数列表),因此无论在哪个环境中构建代码,该函数都将具有一个声明。我们将使用此签名:
func GetURL(url string, r *http.Request) ([]byte, error)
请注意,第二个参数(*http.Request
)仅对AppEngine是必需的(为了能够创建Context
),因此在本地环境的实现中它不被使用(可以甚至是nil
)。
优雅的解决方案可以利用标准环境和AppEngine中可用的http.Client
类型,并且可以用于执行HTTP GET请求。可以在AppEngine上以不同方式获取http.Client
值,但是一旦我们有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
}
答案 1 :(得分:0)
您可以在golang/appengine
项目中找到一些线索。
例如,它的remote_api/client.go
为客户端提供了远程连接到用户生产应用程序的能力。