Is it possible to nest Mux routers?

1,566 views
Skip to first unread message

Karol Stępniewski

unread,
Aug 4, 2014, 5:48:50 PM8/4/14
to goril...@googlegroups.com
Using code below, when I access /test2 it responds with 404 - not found. /test1 works correctly. I guess this happens because "/" matching is exact, so the execution chain doesn't even reach the subRouter. But how should I do it to make it work?

My main goal is to add some initial work which would be common for all routes in subRouter, and only for them. To be even more specific, I would like to use Negroni as my middleware orchiestrator.

I'm familiar with the concept of Subrouter in Mux, but AFAIK I can't use it in similar fashion as example below, in particular, I can't inject anything between mainRouter and its Subrouter. Is this even possible using Mux, or should I look for different Router?

    package main
   
   
import (
   
"fmt"
   
"net/http"
   
"github.com/gorilla/mux"
   
)
   
    func main
() {
   
    mainRouter
:= mux.NewRouter()
    subRouter
:= mux.NewRouter()
   
    mainRouter
.HandleFunc("/test1", func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "test1") })
   
    subRouter
.HandleFunc("/test2", func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "test2") })
   
    mainRouter
.Handle("/", subRouter)
   
    http
.ListenAndServe(":9999", mainRouter)
   
}


On the Negroni website there is an example of adding middleware to the group of routes (which also does not work if adminRoutes has couple of different routes) and this basically what I'm trying to achieve.

    router := mux.NewRouter()
    adminRoutes
:= mux.NewRouter()
   
// add admin routes here
   
   
Create a new negroni for the admin middleware
    router
.Handle("/admin", negroni.New(
     
Middleware1,
     
Middleware2,
      negroni
.Wrap(adminRoutes),
   
))



Matt Silverlock

unread,
Aug 4, 2014, 10:29:50 PM8/4/14
to goril...@googlegroups.com
Just to confirm--since your example seems a bit contrived--do you want the below behaviour:

1. All routes under /admin/* to have a certain set of middleware applied
2. All routes under /something-else/* to have another set of middleware applied
3. All top-level routes under / to set the common middleware that apply to *all* routes.

Is that right?

Note that this is definitely possible with mux + negroni together, but I need to understand your use-case first. You can't do mainRouter.Handle("/", subRouter) like you are doing now. If you really just want to wrap individual routes then you don't even need a sub-router - you just need to mainRouter.HandleFunc("/test2", negroni.New(negroni.NewLogger(), negroni.Wrap(YourHandler)) for that specific route.

Matt Silverlock

unread,
Aug 4, 2014, 10:30:30 PM8/4/14
to goril...@googlegroups.com
(if you can actually provide your *intended* URL/route layout it's much easier to understand what you're getting at).

Karol Stępniewski

unread,
Aug 5, 2014, 7:52:26 AM8/5/14
to goril...@googlegroups.com
Hi Matt,

Thanks for answering. Actually my intended layout looks like that:

"/", "/login", "/register" - routes without middleware

"/upload", "/file", "/history", etc. (couple other routes, but all in "/") - routes with middleware

I wanted to group those middleware-required routes in one router, and then somehow bind it to the main router. I ended up wrapping each handler function individually using wrapping function,  but I don't like this solution.

Matt Silverlock

unread,
Aug 5, 2014, 10:17:27 PM8/5/14
to goril...@googlegroups.com
This is certainly possible, but Negroni isn't my favorite thing in the world and makes things a little complicated since you have to tied in so heavily to it. Have you tried providing your routes/information (your updated info was much clearer) via an issue on the Negroni GitHub repo? I think you may have already done that, but the issue was already closed.

Unless you have a huge amount of middleware you want to re-use (unlikely) you're best of just explicitly re-applying that middleware "chain" to a sub-router and being done with it.

bennAH

unread,
Oct 18, 2015, 5:39:26 PM10/18/15
to Gorilla web toolkit
My bad for resurrecting an old thread, I came across this problem and the following snippet below works for me:



If you try it yourself and run it locally, you will have printed when the following is accessed:

localhost:2022 : no auth - Home
localhost:2022/about : no auth - About
localhost:2022/user:  auth needed - User
localhost:2022/user/account:  auth needed - User Account
Reply all
Reply to author
Forward
0 new messages