Search code examples
gogoji

How can I create separate route groups with different middleware in Goji (Golang)?


I am using Goji (https://github.com/zenazn/goji) and would like to define groups of routes that have their own middleware. For example, all paths under /company should use an LDAP authentication and have a middleware defined to do this. All paths under /external use a different type of authentication so they have a different middleware definition. But this is a single application served on the same port, so I don't want to create separate web services altogether -- just the paths (and some specific routes) may use different middleware.

All the examples I've seen with Goji are using a single set of middleware for all routes, so I am not sure how to accomplish this in a clean way. Additionally it would be nice if I could specify a base path for all routes within a route group, similar to how I've seen in some other routing frameworks.

Am I missing this functionality in the Goji library (or net/http by extension) that allows me to group routes together and have each group use its own middleware stack?

What I would like to achieve is something like this (psedocode):

// Use an LDAP authenticator for:
// GET /company/employees
// and
// POST /company/records
companyGroup = &RouteGroup{"basePath": "/company"}
companyGroup.Use(LDAPAuthenticator)
companyGroup.Add(goji.Get("/employees", Employees.ListAll))
companyGroup.Add(goji.Post("/records", Records.Create))

// Use a special external user authenticator for: GET /external/products
externalGroup = &RouteGroup{"basePath": "/external"}
externalGroup.Use(ExternalUserAuthenticator)
externalGroup.Add(goji.Get("/products", Products.ListAll))

Solution

  • You should be able to solve your problem with something like this:

    // Use an LDAP authenticator 
    companyGroup := web.New()
    companyGroup.Use(LDAPAuthenticator)
    companyGroup.Get("/company/employees", Employees.ListAll)
    companyGroup.Post("/company/records", Records.Create)
    goji.Handle("/company/*", companyGroup)
    
    // Use a special external user authenticator for: GET /external/products
    externalGroup := web.New()
    externalGroup.Use(ExternalUserAuthenticator)
    externalGroup.Get("/external/products", Products.ListAll)
    goji.Handle("/external/*", externalGroup)
    

    You need to give each group its own web. Just keep in mind you need to specify the full path within the group members.