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

Routes generation #39

Closed
ghost opened this issue Feb 5, 2016 · 5 comments
Closed

Routes generation #39

ghost opened this issue Feb 5, 2016 · 5 comments

Comments

@ghost
Copy link

ghost commented Feb 5, 2016

Routes in Goal

Goal's routes package in the auto generated skeleton app is nothing more than a global List variable and calls to the default router:

var List = r.Routes{
    r.Get("/some/path", h.SomeController.SomeAction),
    r.Post(...),
    ...
}
  • Advantages of this approach are:
    1. Router of end-developer's choice, nothing Goal specific.
    2. User can modify routes package and write there whatever code he/she needs.
    3. Type safe (e.g. r.Get will be compiled, r.Gte wont be; h.Controller.Action will, h.Controller.Atcion wont, etc).
  • Disadvantages:
    1. End-developer has to switch between controller file and routes. You're adding a new action, then have to open routes.go to reflect that addition.
    2. We need to implement reverse routes generation (read more about reverse routes in Revel). That means our parser will have to know how to handle the routes.go (so we'll have to introduce Goal specific code or convention).

Proposal

Use annotation like syntax. E.g. in Bottle.py there is:

@route('/hello/<name>')
def greet(name):
    return template('<b>Hello {{name}}</b>!', name=name)

There are no annotations in Go, but other tools such as go generate and go build use tags in comments. That's what we can do, too:

//@get /hello/:name
func (c App) Greet(name string) http.Handler {
    c.Context = name
    return c.Render()
}

Import of actions

Controllers end-developer embeds may include actions with routes. Those can be prefixed as follows:

type App struct {
    // ControllerWithErrorMsgActions contains Error404 action
    // with "@get /404".
    pkg.ControllerWithErrorMsgActions `@route:"/errors/"`
}

//
// The code above is equivalent to writing right in this file:
//

//@get /errors/404
func (c *App) Error404() http.Handler {
    ... // Whatever Error404 of ControllerWithErrorMsgActions controller does.
}

Result of generation

It is supposed the generated code will be similar to:

var Routes = []struct{
    Type, Pattern string
    Handler http.Handler
}{
    {Type: "GET", Pattern: "/hello/:name", Handler: h.App.Greet}
    ...
}

This Routes then can be used by the router (after importing the package where it's located).

For now the variable should be located within generated handlers package (as it is easy to implement). After MVP version will require generation of a new routes package in ./assets/.

Reverse routing

We'll use controllers to generate both routes and reverse routes. A new issue must be open for the latter.

@ghost ghost added this to the v0.0.2 milestone Feb 5, 2016
@ghost
Copy link
Author

ghost commented Feb 13, 2016

This is ready, now we need a new router (or a wrapper around existing router) that would support the generated format.

@ghost ghost added the in-progress label Feb 13, 2016
@xpbliss
Copy link

xpbliss commented Feb 14, 2016

Good! Be quick!

@ghost
Copy link
Author

ghost commented Feb 14, 2016

Some early version of routes generation has been implemented. Packages routes and server were removed from the skeleton app.

TODO: add support of custom 404 and 405 errors without use of ugly global variables in the router. I'm thinking about adding an optional third parameter to the route:

//@get    /errors/404    SOME_PARAMETER_HERE
func (c *App) Error404() http.Handler {
    ...
}

We'll use it to let a router know we want this action to be used in case of SOME_PARAMETER_HERE (e.g. error404 or error405).

@ghost ghost self-assigned this Feb 14, 2016
@xpbliss
Copy link

xpbliss commented Feb 15, 2016

Very good you do !
It is more easy to set the route.
By the way, What is the effect on the label of the route?
And How to use the SOME_PARAMETER_HERE

@ghost ghost removed the in-progress label May 15, 2016
@ghost ghost closed this as completed May 15, 2016
@ghost
Copy link
Author

ghost commented May 15, 2016

I'm working on the next iteration of Goal and rethinking everything. At the moment I'm undecided how far we want to go with the code generation. Do we really need the feature this GH issue introduces? Or do we have to roll back to the routes/routes.go file? I'd like to keep a balance between automation and Go style simplicity / clarity, not turn Goal into something magical. Opinions and thoughts are welcome.

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

No branches or pull requests

1 participant