跨平台go appengine的代码

时间:2016-06-11 09:59:47

标签: google-app-engine go

创建FetchUrl / GetURL函数的GO适当方法是什么?该函数可以从命令行运行,并且可以通过谷歌应用引擎以自定义方式获取网址。

我有基本代码来获取和处理URL上的一些数据。我希望能够从我在桌面上使用的代码中调用它,并将代码部署到app引擎。

希望这清楚,如果不是,请让我知道并且我要澄清。

2 个答案:

答案 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工具忽略。相反,指定

的文件
// +build !appengine
     App Engine SDK会忽略

,而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为客户端提供了远程连接到用户生产应用程序的能力。