Mark Fletcher
Mark Fletcher

Reputation: 751

Golang Gorilla mux, best way to match against two url signatures

Using gorilla mux, I currently have many URLs that are of the form:

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

such that the code looks like:

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

I'd like to also match against:

subdomain.domain.com/{name}/pagename

I know I can do something like

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

to match on the subdomain. Is it possible to only have one HandleFunc() that will match both types of URLs, or do I need to have two HandleFunc()s, one for the first case and one for the subdomain.domain.com case?

Upvotes: 0

Views: 2090

Answers (1)

metakeule
metakeule

Reputation: 3914

With a dispatcher like this you only have to add one line per router/handler.

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)
}

Upvotes: 1

Related Questions