Dynamic routing - changing routing at runtime

1,134 views
Skip to first unread message

Alex Payne

unread,
Mar 25, 2016, 1:14:10 AM3/25/16
to phoenix-talk
Hi, I'm new to Phoenix and Elixir in general, but my company's needs have forced me into a pretty ambitious first project. I need to be able to change the routing for my application at runtime, so that end-users using a cms-like application can change behaviour of their site in real time. I need to change not only the url path routing but also host-name routing, so I can add entirely new websites to the application on the fly. I have a hunch that this will require a pretty custom and low-level implementation, no matter what language/framework I choose, but correct me if I'm wrong. 

So far I can only see one viable solution, to implement my own custom router which uses a tree-like map structure, with hostnames at the root, to determine the routing at runtime. For people more familiar with phoenix/elixir, is this a viable path? Is there something easier or perhaps built-in that I am missing here? Thanks,

Alex

Peter Hamilton

unread,
Mar 25, 2016, 1:40:03 AM3/25/16
to phoenix-talk

Just start with a custom Plug. You may have to build your own router but a simple router isn't too bad. Phoenix routes will likely be more performant but you should be fine. You can even use controllers and the rest of Phoenix on top of your own router, as they are just plugs as well.


--
You received this message because you are subscribed to the Google Groups "phoenix-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to phoenix-talk...@googlegroups.com.
To post to this group, send email to phoeni...@googlegroups.com.
Visit this group at https://groups.google.com/group/phoenix-talk.
To view this discussion on the web visit https://groups.google.com/d/msgid/phoenix-talk/62f412d6-f933-4a8b-b7c8-c18fac1a4358%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Jeff Weiss

unread,
Mar 25, 2016, 3:17:50 AM3/25/16
to phoeni...@googlegroups.com
Alex,

Welcome! Your problem seemed like an interesting challenge, so I threw together a quick proof of concept: https://github.com/jeffweiss/dynamic_routing_example.

tl;dr It's possible, but a ¯\_(ツ)_/¯ idea

Solely for time-to-prototype, I defined the dynamic routes in "priv/wat.json". During compile time, I read the JSON and create scopes and routes based on the content. I opted for this compile-time path as opposed to a plug looking at an in-memory data structure because we can then rely on the speed of the BEAM doing function head matching (and because I assumed that content retrieval happens far more often than content creation). I also added a /reload route that forces the router to recompile and reload the new version into the BEAM.

I was kinda surprised at how easy this was. While this approach works, I still haven't passed judgement on it. Despite requiring the router source to be available in production and the obvious prototype shortcuts of reading everything from disk and monolithic route reloading, I don't feel like it's *clearly* a terrible approach. I don't feel like it's necessarily a great one either though. Would love other folks' assessments.

--
You received this message because you are subscribed to the Google Groups "phoenix-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to phoenix-talk...@googlegroups.com.
To post to this group, send email to phoeni...@googlegroups.com.
Visit this group at https://groups.google.com/group/phoenix-talk.
To view this discussion on the web visit https://groups.google.com/d/msgid/phoenix-talk/62f412d6-f933-4a8b-b7c8-c18fac1a4358%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
¯\_(ツ)_/¯,

Jeff

Chris McCord

unread,
Mar 25, 2016, 7:04:31 AM3/25/16
to phoeni...@googlegroups.com
Something like this is possible within the confines of Phoenix as Peter said. Since you have users very often updating dynamic routes, a precompiled solution is probably too static, so you can instead do something like this:


When your app starts, you would read from cold storage, say a database, and call `DynamicDispatch.register(...)` to register all user routes. Likewise, you would register new routes on-demand based on user actions. The nice thing about this setup is the ets match-spec should be reasonably fast, and you can `forward "/", DynamicDispatch, :my_app_user_routes` in your Phoenix router so you get the best of both worlds for standard routes and user-based dynamic ones. Hope that helps!

–Chris

Alex Payne

unread,
Mar 25, 2016, 11:59:27 AM3/25/16
to phoenix-talk
Thanks so much for all the help, everyone. This is a great community.
Reply all
Reply to author
Forward
0 new messages