rest - 如何在 go-restful 中获取完整的主机和 url

标签 rest http url go go-restful

我正在使用 https://github.com/emicklei/go-restful 在 Go 中编写 REST API

在我的 JSON 输出中,我想输出到其他 REST 资源的绝对路径,但我不知道如何获取构建路径的所有相关部分,例如传输 (http/https)、主机、端口、根路径。

我是否需要自己跟踪它,我是否以某种方式从 Request 中获取它?

最佳答案

玩了一段时间后,我最终尝试了两种方法。事实证明,至少可以从 Request 中提取一些信息(注意:我假设如果路由是用绝对 url 定义的,那么所有这些信息都可以从 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 + "\nHost: " + req.Request.Host + "\nPath: " + req.Request.URL.Path)
}

上面的代码将以下内容打印到浏览器。我想人们可以使用它来构造 url 以进行 jsonify,尽管不清楚如何在没有基本路径或特定路径的先验知识或区分两者的语法约定的情况下解析出基本路径。

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

我尝试的第二件事是在包级别定义一个 URL 并使用它来构建自定义解析函数。 url.URL 维护 URL 的结构表示;可以使用 URL.parse(string) 解析相对(或绝对)路径并将其与现有的 URL 合并。方便的是,URL 可以通过它的 String() 方法输出自身的字符串表示形式。

自定义解析函数只是保留包级别 URL 的副本,每次使用某个特定路径调用它时,它会将新路径粘贴到 的末尾URL.Path 并返回一个新的 URL 除了新的连接路径之外是相同的(因为这就是 URL.parse() 在我们将它交给一个亲戚时所做的小路)。然后可以在新 URL 上调用 URL.String() 以将 URL 字符串化为我们要编码的字符串。

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
} 

这将在浏览器中打印以下内容:

["http://localhost:8080/basepath/get","http://localhost:8080/basepath/put","http://localhost:8080/basepath/whatever"]

关于rest - 如何在 go-restful 中获取完整的主机和 url,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39216053/

相关文章:

c# - 从 HttpResponseMessage.Content 读取流式内容

android - HTTP 请求在网络上有效,但在移动设备上失败? (Yodlee API)

http - 如何使用 AJAX 通过 HTTP 下载文件?

android - 如何在 Android 上的 HttpPost 中发送 unicode 字符

java - 检测并缩短字符串中的所有网址

Angular CLI - 为现在部署设置生产代理

java - 安装 JAX-RS(REST Web 服务)1.1 时失败。 java.lang.NullPointerException异常

java - 在线读取 XML 并存储它(使用 Java)

Sugarcrm 的 REST API

PHP:关于在 URL 中传递参数的问题