radix icon indicating copy to clipboard operation
radix copied to clipboard

Is it possible to add Sub Trees ?

Open dinkopehar opened this issue 2 years ago • 2 comments

Hello.

I found your project radix to be really useful and I discovered it because it's used inside Kemal web framework. Although Kemal is great, I'm looking into making my own simple router using your project.

I'm wondering, is there some solution to sub mounting routes ? For example, Starlette framework has support for that.

I tried some solution, but I end up getting a Tree instead of Result:

require "radix"

users_router = Radix::Tree(String).new
pets_router = Radix::Tree(String).new

users_router.add "/", "All Users"
users_router.add "/login", "Login Users"
users_router.add "/logout", "logout Users"

pets_router.add "/", "Pets"
pets_router.add "/:pet", "Specific Pet"

main_router = Radix::Tree(Radix::Tree(String)).new

main_router.add "/users/", users_router
main_router.add "/pets/", pets_router

result = main_router.find "/users/login" # ???

What I was hoping for is that result would return "All Users" instead of Nil. I assume I'm doing a long stretch here but I'm just curious if this is possible.

Thank you.

dinkopehar avatar Mar 22 '23 18:03 dinkopehar

Hello @dinko-pehar, thank you for your patience.

Can you explain a bit further the thing you're trying to achieve?

This radix implementation is a bit complex and serves only as lookup, but is not a router. Each time a new entry is added the tree gets updated. To perform something like you're asking, it will require to iterate over the inner trees and map that, resulting in duplicate entries in memory. Basically: the pet and user routers only serve to provide the list of entries, but no tree resolution by itself. If not, once find discover another tree as payload, it returns payload.find on that, which might defeat the purpose of having a single radix tree in the first place.

But I might be missing details of what you want to achieve, so it will be better if you can give more concrete examples.

Thank you.

luislavena avatar Apr 12 '23 20:04 luislavena

@luislavena

I was hoping for result = main_router.find "/users/login" in above example to return "Login Users". I didn't really dig exactly into implementation of this radix tree but something similar I found yesterday was on project that is stated in Implementation of README.


For me, I thought to use it with HTTP handlers from Crystal. Basically, having a HTTP Server that first gets a route name with find and than executes HTTP Handler function. I hoped that I could group my project by feature:

| README.md
| shards.yml
| src
  | main.cr              -> Here would be like main router, for example /api/.
  | users
    | models.cr
    | controllers.cr. -> Subrouter that is is registered in main router, so /api/users 
  | pets
    | models.cr.      -> /api/pets
    | controllers.cr
  | shalters
    | models.cr.      
    | controllers.cr

Register subrouter (subtree) in main tree. Tree inside Tree. Not sure if it's clear enough...

dinkopehar avatar Apr 13 '23 14:04 dinkopehar