Skip to content

Gorilla/mux integration #2

@Southclaws

Description

@Southclaws

One of the neat things Rocket.rs does is use function attributes to both declare the route that will bind to a function and specify the variables within a route. See an example of that here: https://rocket.rs/v0.4/guide/requests/#dynamic-paths

This is unfortunately not possible to carbon-copy due to Go's simplicity and minimalism. Also, routing/multiplexing isn't the goal of this library because there are plenty of great libraries for these tasks out there already!

I can however imagine building integrations for popular routers.

Gorilla's Mux library registers routes like this:

r.HandleFunc("/articles/{category}/{sort:(?:asc|desc|new)}", ArticlesCategoryHandler)

That is, the route goes first then the handler. Well, Go will slot the return values of a function into the arguments of another if they are an exact match. So, if Pocket provides a function that returns (string, func(http.ResponseWriter, *http.Request)) then Pocket can have access to the exact route declaration that is passed to Gorilla! Neat!

It would look something like this:

r.HandleFunc(pocket.HandlerGorilla(
    "/articles/{category}/{sort:(?:asc|desc|new)}",
    ArticlesCategoryHandler,
))

Where ArticlesCategoryHandler is a function that has all the magical benefits of Pocket!

So, what would pocket.HandlerGorilla do? It would be something along these lines:

func HandlerGorilla(path string, f interface{}) (
    string,
    func(http.ResponseWriter, *http.Request),
) {
    handler := GenerateHandler(f)

    // parse `path`
    // extract route variables that Gorilla will process - borrow Gorilla code?
    // match these route variables with props in handler.propsT/V
    
    return path, handlerFunc.Execute
}

And on the user side, it would look something like this:

r.HandleFunc(pocket.HandlerGorilla(
	"/articles/{category}/{sort:(?:asc|desc|new)}",
	func(props struct{
		Category string  `route:"category"`
		Sort     SortDir `route:"sort"`
	}) pocket.Responder {
                // perform some business logic with a database using props
		response, err := getData(props.Category, props.Sort)
		if err != nil {
			return pocket.ErrInternalServerError(err)
		}
                // response is some type that satisfies pocket.Responder
		return response
	})
))

(Rough concept, stuff might change)

Here, the props type specifies route tags which map to the {} variables in the route.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions