Import Routes from one App/package into main App/package( like Django Url Imports)


#1

In Django it is easy to import all Urls from one app into main App i.e

url(r"^my_route_path/", include("app.urls")),

I want to do something similar with echo to make it truly robust and re-use my web packages easily. Given a package that already has routes, i want to be able to import those routes easily.
I already can import handlers but it is not very efficient and is very similar to importing Django views.
Django:

url(r'^$', views.index, name='index'),

Golang Echo:

e.GET("/", myauth.Index).Name = "IndexUrl"

I am advocating for something similar to
Echo#Group(prefix string, m ...Middleware) *Group

for example:

Echo#GroupRoutes(prefix string, Echo#Routes() []*Route) 

and usage:

e.GroupRoutes("/myauth", myApp.Echo.Routes())

A similar question was asked here How to load routes from a JSON file? and i suppose it would take similar steps to implement it i.e.
Possible solutions

Should this be implemented as middleware? or stand-alone Echo function?
Please enlighten me on how to proceed with this.


#2

@vishr, can you please explain to me what is going on in the “name” field of a route. I am getting close to working out a solution and would like to know how to correctly parse all the characters - especially at the end.

{
"method": "DELETE",
"path": "/api/*",
"name": "github.com/labstack/echo.(*Group).Use.func1"

},
{
“method”: “POST”,
“path”: “/confirmreset”,
“name”: “github.com/siredwin/myauth/gotin.(User).ConfirmReset-fm”
},


#3

It is the route handler function as string.


#4

Just figured it out! Sharing a supercontext(one instance of echo across packages) is enough to make all routes available without having to import or redefine anything. Too bad no one ever mentioned this.


#5

You can share the same instance but remember they all will be part of routing, configuration, and any middleware that you may have defined.


#6

@vishr, yes i am aware of that , and that is the behavior i desired. Most of my importable, reusable web packages just have routes and no middleware or extra configuration. The main package that starts the server has all the configurations and middleware. So i end up getting a situation where i have Django-like apps and so far it works great.


#7

@siredwin How did you do that?


#8

@rof20004, it is not very hard to implement a multi-app , probably an enterprise level Golang application. But it needs a good example. I can make a blog about it if you want and a link to here.


#9

Thanks @siredwin, I am waiting :smiley:


#10

I will post it here when I get done. My main app currently imports about 8 apps(auth, payments, renderer, blog,etc). One line each.


#11

Thanks @siredwin, take your time :smiley:


#12

This is what I did (helloworld would be your project with subfolders api/routers):

helloworld/main.go

package main

import (
"net/http"
"github.com/labstack/echo"
"github.com/helloworld/api/routers"
)

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

routers.InitRoutes(e)

e.GET("/", func(c echo.Context) error {
 return c.String(http.StatusOK, "hello world")
})

e.Logger.Fatal(e.Start(":1323"))

helloworld/api/routers/router.go:

package routers

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

func InitRoutes(e *echo.Echo) *echo.Echo {
 SetHelloWorldRouters(e)
 //SetSomeOtherRouters(e)
 return e
}

helloworld/api/routers/hello.go

package routers

import (
 "github.com/labstack/echo"
 "github.com/helloworld/api/handlers"
)

func SetHelloWorldRouters(e *echo.Echo) {
 e.GET("/hello", handlers.HelloHandler)
 e.GET("/world", handlers.WorldHandler)
}

I create a router file for each grouping of routes in my helloworld/api/routers/ folder. Handlers are done similiar in the api/handlers folder.

This is working for me. If anyone has a better idea or sees a problem with this approach let me know.


#13

I think your approach is actually good. I will post my initial solution later today or tomorrow. I forgot all about it.


#14

@mbarlow, @rof20004, & everyone else interested. I just posted a simple recipe in GitHub that uses the init function. It is not fully documented but works.
https://github.com/siredwin/multiurlimports

  1. Notice that all routes/URLs go to init in each app/package
  2. The supercontext is important as it initializes our echo instance we will be using for all of our importable apps.
  3. The main app(main.go) just imports the apps with underscores(for side effects). This will give access to the init functions in the imported apps.

I will keep documenting as time goes by. This was a promise i forgot to deliver on.