为了账号安全,请及时绑定邮箱和手机立即绑定

appengine 的跨平台 go 代码

appengine 的跨平台 go 代码

Go
SMILET 2022-01-17 17:54:27
什么是合适的方式来创建 FetchUrl/GetURL 函数,该函数从命令行工作,并通过谷歌应用程序引擎使用其自定义方式获取 url。我有获取和处理 URL 上的一些数据的基本代码。我希望能够从我在桌面上使用的代码以及部署到应用引擎的代码中调用它。希望这很清楚,如果没有,请告诉我并澄清。
查看完整描述

2 回答

?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

如果您有一些代码在本地机器和 AppEngine 环境中都可以工作,那么您无需做任何事情。


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


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


引用Go 博客:App Engine SDK 和工作区(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 需要第二个参数 ( )(以便能够创建 a 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

}


查看完整回答
反对 回复 2022-01-17
?
小唯快跑啊

TA贡献1863条经验 获得超2个赞

golang/appengine您可以在项目本身中获得一些线索。

例如,它remote_api/client.go为客户端提供远程连接到用户的生产应用程序。


查看完整回答
反对 回复 2022-01-17
  • 2 回答
  • 0 关注
  • 227 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信