HTTP routes in different Packages

74 views
Skip to first unread message

Van Fury

unread,
Apr 6, 2021, 10:30:02 AM4/6/21
to golang-nuts

HI,

I have the following settings in my REST API program packages:

In "routers.go"

type Route struct {
    Name        string
    Method      string
    Pattern     string
    HandlerFunc http.HandlerFunc
}

var Router = NewRouter()

type Routes []Route

func NewRouter() *mux.Router {
    router := mux.NewRouter().StrictSlash(true)
    for _, route := range routes {
        var handler http.Handler
        handler = route.HandlerFunc

        router.
            Methods(route.Method).
            Path(route.Pattern).
            Name(route.Name).
            Handler(handler)
    }

    return router
}

func Index(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello World!")
}

var routes = Routes{

    Route{
        "UserData",
        strings.ToUpper("Get"),
        "/{id}/user-data",
        UserData,
    },

    Route{
        "UserData",
        strings.ToUpper("Post"),
        "/{id}/user-data",
        UserData,
    },

    Route{
        "ExampleData",
        strings.ToUpper("Post"),
        "/{id}/example-data",
        ExampleData,
    },

    Route{
        "ExampleData",
        strings.ToUpper("Get"),
        "/{id}/example-data",
        ExampleData,
    },

}

In "main.go"

func main(){

var LISTENING_ADDR = GetListeningAddress()
...

server := NewServer(LISTENING_ADDR)

     go func() {
        err := server.ListenAndServe() // use if http
        if err != nil && err != http.ErrServerClosed {
            logger.Log.Errorf("Could not listen on %s: %v\n", LISTENING_ADDR, err)
            os.Exit(0)
        }
    }()

}

// NewServer - Create a new server
func NewServer(LISTENING_ADDR string) *http.Server {

    return &http.Server{
        Addr:         LISTENING_ADDR,
        Handler:      Router,
        TLSConfig:    TLSConfig(),
        ReadTimeout:  5 * time.Second,
        WriteTimeout: 10 * time.Second,
        IdleTimeout:  120 * time.Second,
    }
}

I have two other packages, example.go and user.go which contain the handler functions.

"example.go"
func ExampleDataPost(w http.Res..., r *http.Req) {
...
}

func ExampleDataGet(w http.Res..., r *http.Req) {
...
}

Also In "user.go" is
func UserDataPost(w http.Res..., r *http.Req) {
...
}

func UserDataGet(w http.Res..., r *http.Req) {
...
}

I would like to move their routes in their respective packages.
I have for example added to "user.go"  what is shown below and the same for "example.go" but my problem is how to call the variables (group routers) "UserNewRouter ", "ExampleNewRouter" in their respective routers in the main.go or the "NewServer".
Any help on how to go about this?

"user.go"

func UserDataPost(w http.Res..., r *http.Req) {
...
}

func UserDataGet(w http.Res..., r *http.Req) {
...
}

type Route struct {
    Name        string
    Method      string
    Pattern     string
    HandlerFunc http.HandlerFunc
}

var UserNewRouter = NewRouter()

type Routes []Route

func NewRouter() *mux.Router {
    router := mux.NewRouter().StrictSlash(true)
    for _, route := range routes {
        var handler http.Handler
        handler = route.HandlerFunc

        router.
            Methods(route.Method).
            Path(route.Pattern).
            Name(route.Name).
            Handler(handler)
    }

    return router
}

var routes = Routes{

    Route{
        "UserDataGet",
        strings.ToUpper("Get"),
        "/{id}/user-data",
        UserDataGet,
    },

    Route{
        "UserDataPost",
        strings.ToUpper("Post"),
        "/{id}/user-data",
        UserDataPost,
    },

}


"example.go"
func ExampleDataPost(w http.Res..., r *http.Req) {
...
}

func ExampleDataGet(w http.Res..., r *http.Req) {
...
}
 
type Route struct {
    Name        string
    Method      string
    Pattern     string
    HandlerFunc http.HandlerFunc
}

var ExampleNewRouter = NewRouter()

type Routes []Route

func NewRouter() *mux.Router {
    router := mux.NewRouter().StrictSlash(true)
    for _, route := range routes {
        var handler http.Handler
        handler = route.HandlerFunc

        router.
            Methods(route.Method).
            Path(route.Pattern).
            Name(route.Name).
            Handler(handler)
    }

    return router
}

var routes = Routes{
    Route{
        "ExampleDataPost",
        strings.ToUpper("Post"),
        "/{id}/example-data",
        ExampleDataPost,
    },

    Route{
        "ExampleDataGet",
        strings.ToUpper("Get"),
        "/{id}/example-data",
        ExampleDataGet,
    },
}

BR
Fury

Brian Candler

unread,
Apr 6, 2021, 11:47:58 AM4/6/21
to golang-nuts
It's unclear when you say "I have two other packages, example.go and user.go which contain the handler functions."

If these files are all in the same directory, then they are all be part of the *same* package.  For example, they'll all have "package main" as the first line.  Since you don't show the complete files, I can't see this, but that's how it should be.

Splitting functions and global variables between files in the same package is easy: you can move them around at will, since they're all part of the same package namespace.  The only changes you'll need to make is to ensure the "import" statements at the top of each source file import any external packages used by the code in that source file.

If you want to make separate packages, then each package has to be in its own subdirectory.  But since you didn't mention directories, I don't think this is what you're doing.

Brian Candler

unread,
Apr 6, 2021, 11:55:05 AM4/6/21
to golang-nuts
Message has been deleted

Van Fury

unread,
Apr 6, 2021, 12:15:52 PM4/6/21
to golang-nuts
"I have two other packages, example.go and user.go"  - I mean these files example.go and user.go are in different directories not the same package,
and have the package names "package example" and "package user". The main.go is also in different directory with "package main".

David Fornazier

unread,
Apr 6, 2021, 1:22:35 PM4/6/21
to golang-nuts
Hello!

You could create in your packages a function that receives  a  *http.ServeMux, by this reference you can configure you're path an function related.

Example:
"example.go"

func FooPath(mux *http.ServeMux) {
    mux.HandleFunc("/foo", exampleFoo)
}

func exampleFoo(w http.Res..., r *http.Req) {
    json.NewEncoder(w).Encode("Hi there!")
}

-----
...
-----

"routes.go"

fun main() {
    //router
    mux := http.NewServeMux()
   
    //config the paths
    example.FooPath(mux)
   
    s := &http.Server{
        Addr:           "localhost:1324",
        Handler:        mux,
        ReadTimeout:    10 * time.Second,
        WriteTimeout:   10 * time.Second,
    }
    log.Fatal(s.ListenAndServe())
}
Reply all
Reply to author
Forward
0 new messages