duanmeng9336 2016-08-29 22:19
浏览 141
已采纳

如何在Go-restful中获得完整的主机和URL

I'm writing a REST API in Go using https://github.com/emicklei/go-restful

In my JSON output I want to output absolute path to other REST resources, but I don't know how I can obtain all the relevant parts to build the Path, such as transport (http/https), host, port, root path.

Do I need to keep track of this myself, do I fetch it from the Request somehow?

  • 写回答

1条回答 默认 最新

  • doucheng1944 2016-08-30 00:32
    关注

    After playing with this for a while, I ended up trying it both ways. It turns out that at least some of the information can be extracted from Request (note: I presume that if the route were defined with an absolute url then all of this information could be had from Request.URL)

    package main
    
    import (
        "github.com/emicklei/go-restful"
        "io"
        "net/http"
    )
    
    func main() {
        ws := new(restful.WebService)
        ws.Route(ws.GET("/hello").To(hello))
        restful.Add(ws)
        http.ListenAndServe(":8080", nil)
    }
    
    func hello(req *restful.Request, resp *restful.Response) {
        io.WriteString(resp, "Protocol: " + req.Request.Proto + "
    Host: " + req.Request.Host + "
    Path: " + req.Request.URL.Path)
    }
    

    The above prints the following to the browser. I suppose one could use this to construct urls to jsonify, although it's not clear how the base path would be parsed out without some prior knowledge of either the base path or the specific path, or some syntactic convention for distinguishing the two.

    Protocol: HTTP/1.1
    Host: localhost:8080
    Path: /hello
    

    The second thing I tried was to define a URL at package level and use that to build a custom parse function. url.URL maintains a struct representation of a URL; A relative (or absolute) path can be parsed and merged with an existing URL using URL.parse(string). Conveniently, URL can output a string representation of itself via it's String() method.

    The custom parse function simply holds on to a copy of the package level URL, and each time it is called with some specific path it pastes the new path on to the end of the URL.Path and returns a new URL that's identical except for the new concatenated path (because that's what URL.parse() does when we hand it a relative path). URL.String() can then be called on the new URL to stringify the URL into the string that we want to marshal.

    package main
    
    import (
        "github.com/emicklei/go-restful"
        "io"
        "net/http"
        "net/url"
        "fmt"
        "encoding/json"
    )
    
    var myurl = url.URL{
    Scheme:"http",
    Host: "localhost:8080",
    Path:"basepath",
    }
    
    var parse = getParseFn(myurl)
    
    func main() {
        ws := new(restful.WebService)
        ws.Route(ws.GET("/jsonUrls").To(jsonUrls))
        restful.Add(ws)
        http.ListenAndServe(":8080", nil)
    }
    
    func jsonUrls(req *restful.Request, resp *restful.Response) {
        urls := []string{}
        for _, s := range []string{"get", "put", "whatever"} {
            u, err := parse(s)
            if err != nil {
                fmt.Println(err)
            }
            urls = append(urls, u.String())
        }
        json_urls, err := json.Marshal(urls)
        if err != nil {
            fmt.Println(err)
        }
        io.WriteString(resp, string(json_urls))
    }
    
    func getParseFn (myUrl url.URL) func (string) (*url.URL, error) {
        parse := func (s string) (*url.URL, error) {
            u, err := myUrl.Parse(myUrl.Path + "/" + s)
            return u, err
        }
        return parse
    } 
    

    This prints the following in the browser:

    ["http://localhost:8080/basepath/get","http://localhost:8080/basepath/put","http://localhost:8080/basepath/whatever"]
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 Python爬取指定微博话题下的内容,保存为txt
  • ¥15 vue2登录调用后端接口如何实现
  • ¥65 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥15 latex怎么处理论文引理引用参考文献
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?