【问题标题】:Golang Gorilla mux, best way to match against two url signaturesGolang Gorilla mux,匹配两个 url 签名的最佳方式
【发布时间】:2015-07-10 12:06:07
【问题描述】:

使用 gorilla mux,我目前有许多 URL 格式为:

domain.com/org/{subdomain}/{name}/pagename

这样代码看起来像:

rtr.HandleFunc("/org/{subdomain}/{name}/promote", promoteView)

我也想匹配:

subdomain.domain.com/{name}/pagename

我知道我可以做类似的事情

rtr.Host("{subdomain:[a-z]+}.domain.com").HandleFunc("/{name}/promote", promoteView)

匹配子域。是否可能只有一个 HandleFunc() 可以匹配两种类型的 URL,或者我需要两个 HandleFunc(),一个用于第一种情况,一个用于 subdomain.domain.com 情况?

【问题讨论】:

  • 将它们作为 2 条路线处理有什么问题?它们都可以指向同一个处理函数。您必须以某种方式声明路径和主机,所以没有真正的方法可以缩短它。
  • 我有大约 100 个处理程序,并希望避免代码膨胀/维护问题,因为每个处理程序都有重复的路线。
  • @MarkFletcher 查看我的解决方案
  • 你这里有 2 条路由,所以你需要以某种方式定义它们,单独列出它们可能会使维护更容易。如果将主机+名称对组合成处理程序映射(la metakeule 的答案)对您也不起作用,那么我认为您需要为您要解决的问题提供更好的示例。

标签: go gorilla


【解决方案1】:

使用这样的调度程序,您只需为每个路由器/处理程序添加一条线路。

package main

import (
    "fmt"
    "github.com/gorilla/mux"
    "net/http"
)

type key struct {
    subdomain, name string
}

type dispatcher map[key]http.Handler

func (d dispatcher) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    handler, ok := d[key{vars["subdomain"], vars["name"]}]

    if ok {
        handler.ServeHTTP(w, r)
        return
    }
    http.NotFound(w, r)
}

func handleA(rw http.ResponseWriter, req *http.Request) {
    fmt.Fprintln(rw, "handleA serving")
}

func handleB(rw http.ResponseWriter, req *http.Request) {
    fmt.Fprintln(rw, "handleB serving")
}

var Dispatcher = dispatcher{
    key{"subA", "nameA"}: http.HandlerFunc(handleA),
    key{"subB", "nameB"}: http.HandlerFunc(handleB),
    // add your new routes here
}

func main() {
    r := mux.NewRouter()
    r.Handle("/org/{subdomain}/{name}/promote", Dispatcher)
    r.Host("{subdomain:[a-z]+}.domain.com").Path("/{name}/promote").Handler(Dispatcher)

    http.ListenAndServe(":8080", r)
}

【讨论】:

  • 对不起,这可能是一个愚蠢的问题(但我通过这种方式了解更多信息) - 请您解释一下这种 Dispatcher 方法如何减少代码,因为上面的代码同时具有 r.Handler.Host 调用来自 OP。实现相同目标的方法似乎不同,我错过了什么?
  • 它只是让为域和名称的组合添加更多处理程序变得容易。我猜这是最终目标。假设您有 20 个域名/名称处理程序,只需编写处理程序并为每个处理程序添加一个新条目到 Dispatcher。
  • 这不会改变任何路由,添加新的处理程序对仍然需要几乎完全相同的 2 行。您所做的只是将代码添加到原始 promoteView 函数中,并使其成为 http.Handler
  • @JimB 是的,那又怎样?整个事情只有在调度的上下文中才有意义,所以我试图提供一个完整的解决方案。还解决了 Mark "I've got about 100 handlers..." from above 的评论
猜你喜欢
  • 2020-08-19
  • 1970-01-01
  • 2020-06-06
  • 2021-06-05
  • 2014-02-09
  • 1970-01-01
  • 2016-10-01
  • 2018-07-30
  • 1970-01-01
相关资源
最近更新 更多