douli8428 2017-10-04 14:38
浏览 405

使用gin路由器在Golang中处理动态子域的最佳方法是什么

Hello Everyone,

I am working on a project where I need to setup the multiple sub-domains with the routes. I tried code with two sub-domains, but in my case it would be 100 sub-domains. I tried the following code for this:

package main

import (
    "github.com/gin-gonic/gin"
    "net/http"
    "strings"
)

type Subdomains map[string]http.Handler

func (subdomains Subdomains) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    domainParts := strings.Split(r.Host, ".")

    if mux := subdomains[domainParts[0]]; mux != nil {
        mux.ServeHTTP(w, r)
    } else {
        http.Error(w, "Not found", 404)
    }
}

func main() {
    r := gin.Default()
    r2 := gin.Default()
    hs := make(Subdomains)
    hs["admin"] = r
    hs["analytics"] = r2
    r.GET("/ping", adminHandlerOne)
    r2.GET("/ping", adminHandlerOne)
    http.ListenAndServe(":9090", hs)
}
func adminHandlerOne(c *gin.Context) {
    c.JSON(200, gin.H{
        "message": "pong",
    })
}

But I think that this is not good. Is anybody know the proper way to do this?

  • 写回答

2条回答 默认 最新

  • doucheng1884 2017-10-04 21:03
    关注

    You have a few options (write a router, write wrappers, attempt to bend gin to your will), but as the default ServeMux supports this, and you probably really don't need gin in particular, I'd go with the standard router. Take a look at the source of the DefaultServeMux first, to get an idea of how simple a router is at heart - a router is just a map of paths to handlers.

    The Default ServeMux actually does what you want (allows matching on host as well as path), so I'd suggest trying with that first. Register your patterns:

    mux := http.NewServeMux()
    mux.HandleFunc("/", handlerRoot)
    mux.HandleFunc("analytics.example.com/", handlerOne)
    mux.HandleFunc("admin.example.com/", handlerTwo)
    err := http.ListenAndServe(":9090", mux)
    if err != nil {
        panic(err)
    }
    

    Write some handlers (obviously you might write json with an encoder rather than directly, this is just an example):

    func handlerOne(w http.ResponseWriter, r *http.Request) {
        j := fmt.Sprintf(`{"one":"%s"}`, r.Host)
        w.Header().Set("Content-Type", "application/json")
        w.WriteHeader(http.StatusOK)
        w.Write([]byte(j))
    }
    

    If you're then testing this on localhost, you'd probably want to edit your /etc/hosts file to be sure you hit the server with the right hostname.

    Putting that together, you could use something like this to test with:

    https://play.golang.org/p/ut-GT_s3Gf

    Note these subdomains could be dynamic if you want (the mention of 100 plus makes me think they might be), and you could just customise behaviour at runtime in handlers rather than using separate handlers, it depends how differently the domains behave.

    评论

报告相同问题?

悬赏问题

  • ¥15 GDI处理通道视频时总是带有白色锯齿
  • ¥20 用雷电模拟器安装百达屋apk一直闪退
  • ¥15 算能科技20240506咨询(拒绝大模型回答)
  • ¥15 自适应 AR 模型 参数估计Matlab程序
  • ¥100 角动量包络面如何用MATLAB绘制
  • ¥15 merge函数占用内存过大
  • ¥15 Revit2020下载问题
  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大
  • ¥15 单片机无法进入HAL_TIM_PWM_PulseFinishedCallback回调函数