Search code examples
gomiddleware

Go: How to Handle Package Collisions without Renaming?


I'm trying to solve a package collision without renaming, as i don't think it's particularly elegant. So at the moment I have my own middleware which just handles database connections, but I also use middleware from Echo. Echo uses middleware as their middleware's package name too.

So the solution i'm trying to implement is one in which would extend Echo's package. But i'm not having any success and have not found any info on doing this.

See echo middleware here: https://github.com/labstack/echo/tree/master/middleware

main.go

package main


import (
    "github.com/facebookgo/grace/gracehttp"
    "github.com/labstack/echo"
    "github.com/labstack/echo/engine/standard"
    "gitlab.com/project/middleware" //This is the middleware repository
    "github.com/asaskevich/govalidator"
    "gopkg.in/mgo.v2"
    "gopkg.in/mgo.v2/bson"
    "encoding/json"
    "log"
)


func main() {
    e := echo.New()

    e.Use(middleware.Db()) //Custom middleware
    e.Use(middleware.Logger()) //Echo middleware
    e.Use(middleware.Recover()) //Echo middleware

    //Compile fails because Logger and Recover are not being exported.

    e.Post("/", createUser())
    e.Get("/", getUser())
    e.Put("/", updateUser())
    e.Delete("/", removeUser())

    s := standard.New(":3000")
    s.SetHandler(e)
    gracehttp.Serve(s.Server)
}

Middleware structure

├── middleware
│   ├── db.go //Custom middleware
│   └── echo.go //Echo middleware

So db.go and echo.go are both packaged as middleware, but I'm not able to 'export' the functions from the Echo package which is imported.

echo.go

package middleware

import (
    . "github.com/labstack/echo/middleware"
)

//Stop compiler errors
//Echo middleware is usually accessed with middleware.Logger
//But by using the preceding dot, you can drop the prefix
var _ = Logger()

GO's compiling fails because Logger() and Recover() function are not exported despite being capitalised - whereas Db() from the db.go package is exported.


Solution

  • Your import solution doesn't work because even if the echo middleware package is imported without identifier, its exported identified aren't part of your middleware package. The dot import is simply a syntaxic sugar… one that's not recommended to use by the way.

    If you really don't want to use the package renaming (which is the better solution IMHO), you can define your own methods to create the middlewares in your package.

    package middleware
    
    import "github.com/labstack/echo"
    import "github.com/labstack/echo/middleware"
    
    func Logger () echo.MiddlewareFunc {
        return middleware.Logger()
    }
    

    This would effectively remove the need for the echo/middleware package in you main code, at the cost of duplicate code that's not really needed.