Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use specific middleware for specific routes #25

Closed
jamiefoster opened this issue Jun 24, 2014 · 17 comments
Closed

Use specific middleware for specific routes #25

jamiefoster opened this issue Jun 24, 2014 · 17 comments

Comments

@jamiefoster
Copy link

What is the easiest way to specify a middleware (auth for example) for a group of routes and another middleware (or none) for another group of routes in the same app?

@alehano
Copy link

alehano commented Jun 24, 2014

+1

1 similar comment
@muei
Copy link

muei commented Jun 26, 2014

+1

@codegangsta
Copy link
Contributor

This is where Negroni's modularity excels. If your router supports http.Handler or http.HandlerFunc for your route handlers (which it should), you can just create a new instance of negroni and use that as your middleware stack for the specific route, here is an example in gorilla mux:

n := negroni.Classic()

r := mux.NewRouter()
r.Handle("/admin", negroni.New(Middleware1, Middleware2, AdminHandler))
n.UseHandler(r)

n.Run(":3000")

With AdminHandler being your route handler.

Hope that helps!

@jamiefoster
Copy link
Author

Thank you for the reply.
Has anyone tried this with https://github.com/julienschmidt/httprouter ?

@codegangsta
Copy link
Contributor

Httprouter supports http.Handler with the Handler method. So it should work great. Only limitation is that you won't be getting httprouter params for the top level route in the nesting, but that is a problem with nesting in general.

You could possibly make use of closures, but in all likeliness you wouldn't have this restriction work against you in most situations

Sent from my iPhone

On Jun 27, 2014, at 8:12 AM, Jamie Foster notifications@github.com wrote:

Thank you for the reply.
Has anyone tried this with https://github.com/julienschmidt/httprouter ?


Reply to this email directly or view it on GitHub.

@codegangsta
Copy link
Contributor

Yup, you can create as many negroni instances as you want, they are just http.Handlers and pretty lightweight.
On Jun 27, 2014, at 9:00 AM, Jamie Foster notifications@github.com wrote:

In case i need two routes using a middleware and a third route using another middleware, would I write something like this?

n := negroni.Classic()

r := mux.NewRouter()
r.Handle("/route1", negroni.New(Middleware1,UnrestrictedHandlerRoute1))
r.Handle("/admin", negroni.New(Middleware1, Middleware2, AdminHandler))
n.UseHandler(r)

n.Run(":3000")


Reply to this email directly or view it on GitHub.

@codegangsta
Copy link
Contributor

closing as it looks like this issue is resolved

@alehano
Copy link

alehano commented Jul 9, 2014

It would be great if this info was in readme file.

@romanodesouza
Copy link

It would be great if this info was in readme file.

+1

@marcosnils
Copy link
Contributor

Hi, I'm trying to make this work using gorilla and negroni but I can't seem to find the correct solution. This is the way I'm trying to do this:

        n := negroni.Classic()
        r := mux.NewRouter()
        ac := mux.NewRouter()
        ac.HandleFunc("/accounts", createHandler)
        ac.HandleFunc("/accounts/{id}/password_reset_tokens", sendPasswordResetTokenHandler)                                                                                                                                                        
        r.Handle("/accounts", negroni.New(
                &middleware.BasicAuth{},
                negroni.Wrap(ac),
        ))

       n.UseHandler(r)

       n.Run(":3000")

After negroni starts, if I call the /accounts URI it works and calls the createHandler with the specified middlewares. However, whenever I try to call the /accounts/{id}/password_reset_tokens I get a 404 response from negorni / gorilla.

Can you please point me the correct way of applying a middleware for several routes?

Thanks!.

@marcosnils
Copy link
Contributor

I already found how it should be done. Instead of using r.Handle I've changed it to r.PathPrefix("/accounts").Handler(.....

That did the trick.

@dimroc
Copy link

dimroc commented May 23, 2015

Thanks @marcosnils. Put me in the right direction.

@marcosnils
Copy link
Contributor

@dimroc glad it helped :)

@aubm
Copy link

aubm commented Mar 26, 2016

Hey there :)

I might need a bit of help for this. For what I understand, the following should work:

router := mux.NewRouter()

booksRouter := mux.NewRouter()
booksRouter.HandleFunc("/", getBooks).Methods("GET")
booksRouter.HandleFunc("/", createBook).Methods("GET")
booksRouter.HandleFunc("/{bookId}", updateBook).Methods("PUT")
booksRouter.HandleFunc("/{bookId}", getOneBook).Methods("GET")
booksRouter.HandleFunc("/{bookId}", deleteOneBook).Methods("DELETE")
router.PathPrefix("/api/libraries/{libraryId}/books").Handler(negroni.New(negroni.Wrap(booksRouter)))

librariesRouter := mux.NewRouter()
librariesRouter.HandleFunc("/", getLibraries).Methods("GET")
librariesRouter.HandleFunc("/", createLibrary).Methods("POST")
librariesRouter.HandleFunc("/{libraryId}", updateLibrary).Methods("PUT")
librariesRouter.HandleFunc("/{libraryId}", getOneLibrary).Methods("GET")
librariesRouter.HandleFunc("/{libraryId}", deleteLibrary).Methods("DELETE")
router.PathPrefix("/api/libraries").Handler(negroni.New(negroni.Wrap(librariesRouter)))

n := negroni.New()
n.UseHandler(router)

n.Run(":8080")

Sadly, I fail to see why any request ends up with a 404 status code. The idea behind that is to be able to execute a middleware only for /api/libraries/{libraryId}/books routes.

Any ideas?

@brstos
Copy link

brstos commented May 15, 2016

Hey @aubm

When you access your endpoints it is handled by router that redirects to booksRouter or librariesRouter. The problem is that when it's redirected there is no mappings for the called endpoint. The routers for books and libraries are not subrouters for router. So you must specify the complete mapping in order to be able to handle the requests. Use it instead...

router := mux.NewRouter()

booksRouter := mux.NewRouter()
booksRouter.HandleFunc("/api/libraries/{libraryId}/books", getBooks).Methods("GET")
booksRouter.HandleFunc("/api/libraries/{libraryId}/books", createBook).Methods("GET")
booksRouter.HandleFunc("/api/libraries/{libraryId}/books/{bookId}", updateBook).Methods("PUT")
booksRouter.HandleFunc("/api/libraries/{libraryId}/books/{bookId}", getOneBook).Methods("GET")
booksRouter.HandleFunc("/api/libraries/{libraryId}/books/{bookId}", deleteOneBook).Methods("DELETE")
router.PathPrefix("/api/libraries/{libraryId}/books").Handler(negroni.New(negroni.Wrap(booksRouter)))

librariesRouter := mux.NewRouter()
librariesRouter.HandleFunc("/api/libraries", getLibraries).Methods("GET")
librariesRouter.HandleFunc("/api/libraries", createLibrary).Methods("POST")
librariesRouter.HandleFunc("/api/libraries/{libraryId}", updateLibrary).Methods("PUT")
librariesRouter.HandleFunc("/api/libraries/{libraryId}", getOneLibrary).Methods("GET")
librariesRouter.HandleFunc("/api/libraries/{libraryId}", deleteLibrary).Methods("DELETE")
router.PathPrefix("/api/libraries").Handler(negroni.New(negroni.Wrap(librariesRouter)))

n := negroni.New()
n.UseHandler(router)

n.Run(":8080")

@aubm
Copy link

aubm commented May 19, 2016

Hey @brstos :)

Thank you for your answer, it makes sens to me.
I'll give it a try,

Cheers,

@pawanrawal
Copy link

I am trying to apply a middleware to the routes with a subrouter, as shown https://github.com/dgraph-io/gru/blob/feature/invite-candidate/gruadmin/main.go#L124. Though the jwt middleware isn't hit and the route is hit directly?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants