dsfhe34889 2016-06-11 09:59
浏览 15
已采纳

适用于Appengine的跨平台Go代码

What is the GO appropriate way to create a FetchUrl/GetURL function that works from the command line and works from google app engine with its custom way to fetch a url.

I have basic code that fetches and processes some data on a URL. I want to be able to call it from code I use on my desktop, and code deployed to app engine.

Hopefully thats clear, if not please let me know and Ill clarify.

  • 写回答

2条回答 默认 最新

  • doudeng2057 2016-06-11 12:14
    关注

    If you have some code which works both on local machine and on AppEngine environment, you have nothing to do.

    If you need to do something which should or must be done differently on AppEngine, then you need to detect the environment and write different code for the different environments.

    This detection and code selection is easiest done using build constraints. You can put a special comment line in the beginning of your .go file, and it may or may not be compiled and run depending on the environment.

    Quoting from 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.

    So for example you can have 2 separate .go files, one for AppEngine and one for local (non-AppEngine) environment. Define the same function in both (with same parameter list), so no matter in which environment the code is built, the function will have one declaration. We will use this signature:

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

    Note that the 2nd parameter (*http.Request) is only required for the AppEngine (in order to be able to create a Context), so in the implementation for local env it is not used (can even be nil).

    An elegant solution can take advantage of the http.Client type which is available in both the standard environment and in AppEngine, and which can be used to do an HTTP GET request. An http.Client value can be acquired differently on AppEngine, but once we have an http.Client value, we can proceed the same way. So we will have a common code that receives an http.Client and can do the rest.

    Example implementation can look like this:

    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条)

报告相同问题?

悬赏问题

  • ¥15 请问如何在openpcdet上对KITTI数据集的测试集进行结果评估?
  • ¥15 powerbuilder中的datawindow数据整合到新的DataWindow
  • ¥20 有人知道这种图怎么画吗?
  • ¥15 pyqt6如何引用qrc文件加载里面的的资源
  • ¥15 安卓JNI项目使用lua上的问题
  • ¥20 RL+GNN解决人员排班问题时梯度消失
  • ¥60 要数控稳压电源测试数据
  • ¥15 能帮我写下这个编程吗
  • ¥15 ikuai客户端l2tp协议链接报终止15信号和无法将p.p.p6转换为我的l2tp线路
  • ¥15 phython读取excel表格报错 ^7个 SyntaxError: invalid syntax 语句报错