0

我刚开始使用 Golang,我想在 Go 中重新制作我已经工作的 NodeJS/TypeScript 应用程序。

我的 API 的一个端点只是添加了服务器端生成的授权标头并将请求发送到远程 API。基本上通过调用我的 API 而不是远程 API 来为我填充这些标题。

这是我目前正在写的

func Endpoint(ctx *fiber.Ctx) error {
    url := "https://api.twitch.tv" + ctx.OriginalURL()

    req, _ := http.NewRequest(http.MethodGet, url, nil)

    req.Header.Set("Authorization", "Bearer ---------")
    req.Header.Set("Client-Id", "---------")

    client := &http.Client{}
    res, err := client.Do(req)

    // temporary error handling
    if err != nil {
        log.Fatalln(err)
    }

    body, err := ioutil.ReadAll(res.Body)

    // temporary error handling
    if err != nil {
        log.Fatalln(err)
    }

    var forwardedBody interface{}

    json.Unmarshal(body, &forwardedBody)

    return ctx.Status(fiber.StatusOK).JSON(forwardedBody)
}

我想知道我是否走在正确的步骤上,因为发出请求,使用 ioutil 解析 JSON 响应,然后将其解组以将其发送回来,这对于我想要实现的简单性来说似乎有点过火了?

编辑:谢谢你的帮助,这就是我想要的

func Endpoint(ctx *fiber.Ctx) error {
    url := "https://api.twitch.tv" + ctx.OriginalURL()

    req, _ := http.NewRequest(http.MethodGet, url, nil)

    req.Header.Set("Authorization", "Bearer ---------")
    req.Header.Set("Client-ID", "---------")

    client := &http.Client{}
    res, err := client.Do(req)

    if err != nil {
        return ctx.SendStatus(fiber.StatusBadRequest)
    }

    ctx.Set("Content-Type", "application/json; charset=utf-8")

    return ctx.Status(res.StatusCode).SendStream(res.Body)
}
4

2 回答 2

1

您可以使用httputil.ReverseProxy。它采用基本 URL 并将请求转发到基本 URL,连接路径。

ReverseProxy 是一个 HTTP 处理程序,它接受传入请求并将其发送到另一台服务器,将响应代理回客户端。

http.Handle("/", &httputil.ReverseProxy{
    Director: func(r *http.Request) {
        r.URL.Scheme = "https"
        r.URL.Host = "go.dev"
        r.Host = r.URL.Host
        r.Header.Set("X-Foo", "Bar")
    },
})

如果您不是从根路径提供此服务,则/可以使用StripPrefix

http.HandleFunc("/foo/", http.StripPrefix("/foo/", proxy)

还有一个辅助函数NewSingleHostReverseProxy,它可能消除了自己配置代理结构的需要。但我认为将 Host 标头与您的自定义标头一起设置会更好。

于 2022-02-05T17:47:01.223 回答
0

您无需尝试将数据解析为 JSON。如果您的任何端点不返回 JSON,这将是有问题的,因此只需将正文直接注入响应中:

body, err := ioutil.ReadAll(res.Body)

// temporary error handling
if err != nil {
    log.Fatalln(err)
}

// Inject the body from the inner response into the actual response so it can be returned
ctx.Response().SetBody(body)

return cx.Status(fiber.StatusOK)

于 2022-02-05T02:13:53.413 回答