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

use for non-http #67

Closed
pjebs opened this issue Jul 9, 2019 · 4 comments
Closed

use for non-http #67

pjebs opened this issue Jul 9, 2019 · 4 comments

Comments

@pjebs
Copy link

pjebs commented Jul 9, 2019

Is there a way to use this for non-http scenarios. I only need the path routing implementation. i.e. string -> parse -> call a function based on arguments in "route" path

@pjebs pjebs changed the title use for not http use for non-http Jul 9, 2019
@dimfeld
Copy link
Owner

dimfeld commented Jul 9, 2019

Not out of the box, but pretty much all the logic you want is contained in tree.go so you could copy that file and use it in your project. Its interface isn't really designed for external usage, so you would probably want to write a few wrapper functions around the code snippets below to make it nicer to use.

With the caveat that I haven't tried it, I think something like this should work:

First, instantiate the root of the tree.

root := &node{ path: "/" }

Then add routes to it.

n := root.addPath("a/path/with/:wildcard/:anotherWildcard", nil, false)
n.setHandler("GET", myFunction, false)

Here I'm just calling it with the GET method all the time to keep things simple. For reference, here's the original code with all the extra HTTP stuff that you don't need.

httptreemux/group.go

Lines 96 to 106 in a454a10

addOne := func(thePath string) {
node := g.mux.root.addPath(thePath[1:], nil, false)
if addSlash {
node.addSlash = true
}
node.setHandler(method, handler, false)
if g.mux.HeadCanUseGet && method == "GET" && node.leafHandler["HEAD"] == nil {
node.setHandler("HEAD", handler, true)
}
}

And later look it up (removing the leading slash if there is one)

path := "/a/path/with/a/value"
n, handler, params := root.search("GET", path[1:])

Then process the results.

if handler != nil {
  // Found it!
  // params[0] == "a" and params[1] == "value". 
  handler(params)
}

The returned wildcard parameters are in a slice by default. The code to make these into a map with named parameters, if you want, is

httptreemux/router.go

Lines 188 to 201 in a454a10

var paramMap map[string]string
if len(params) != 0 {
if len(params) != len(n.leafWildcardNames) {
// Need better behavior here. Should this be a panic?
panic(fmt.Sprintf("httptreemux parameter list length mismatch: %v, %v",
params, n.leafWildcardNames))
}
paramMap = make(map[string]string)
numParams := len(params)
for index := 0; index < numParams; index++ {
paramMap[n.leafWildcardNames[numParams-index-1]] = params[index]
}
}

These snippets don't take into account the trailing slash behavior, so if you care about that you can find the relevant parts throughout the code base by searching for trailingSlash and addSlash.

You would also want to change the various references to HandlerFunc to be whatever function prototype you want, and depending on how much work you want to do, maybe remove all the HTTP method specific stuff in tree.go, which mostly entails changing leafHandler into just a single function type instead of a map.

Hope this helps!

@pjebs
Copy link
Author

pjebs commented Jul 9, 2019

how would I add a mutex so i can modify the routes at runtime?

@dimfeld
Copy link
Owner

dimfeld commented Jul 9, 2019

Same as anything else that needs thread safety. Wrap the calls to add new routes and the calls to search with an RWMutex or whatever you deem most appropriate. The router already has an option to do this so you can see how it does it by looking through the code.

@pjebs
Copy link
Author

pjebs commented Jul 10, 2019

thank you @dimfeld

@dimfeld dimfeld closed this as completed Jul 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants