leafo / lapis

A web framework for Lua and OpenResty written in MoonScript
http://leafo.net/lapis/
MIT License
3.12k stars 247 forks source link

Design Advice #169

Open lordnynex opened 10 years ago

lordnynex commented 10 years ago

Hello,

I'm looking for some guidance on dynamic routing. I need to store dynamic routes/responses in a cache backed database. What I'm thinking is abusing default_route and kicking off a secondary router? This really feels sortof overkill because I noticed add_route in Router. I guess this leaves me with two questions.

I guess I'm trying to avoid duplicating all the lpeg logic in a secondary router that is exactly the same. I've been wondering for a little bit if it's possible to add arbitrary functions to classes.

lordnynex commented 10 years ago

Also worth mentioning, I'd like to create a generic dispatcher and am a little unclear on the syntax/pattern behind this. If I can insert everything as a named route, my dispatcher can grab it's response object out of the appropriate cache.

leafo commented 10 years ago

Can you give me an example of the kinds of dynamic routes you need to capture? They aren't something that can match a pattern like /hello/:world? Chances are you don't need to manipulate the routes at run time.

The Router class which does routing is a completely standalone class, it's easy to create your own to match anything with, here's an example of it being used: https://github.com/leafo/lapis/blob/master/spec/routes_spec.moon

For an app, the existing router can be manipulated as well. If you call @app.router\add_route then the pattern cache on the router is cleared and it will be rebuilt next time it serves a route. There's no way to remove a route at the moment though so be careful of memory leaks. Use the @wrap_handler method on application to convert a action function to the function you pass to the second argument of add_route.

lordnynex commented 10 years ago

Hello,

I am attempting to match routes like /hello/:world. I just did a few tests creating a secondary Router object and it works great. If I'm understanding your response correctly it seems that this approach has the added benefit of being a bit safer from memory leaks.

I'm curious about a few things that popped up (in list order for organization)

DynamicRouter = require("lib.DynamicRouter")!

class App extends lapis.Application
  default_route: =>
    DynamicRouter\handleRequest @

_EDIT_ I think whats got me most confused is how to maintain global state on this DynamicRouter object.

If I have a controller/app elsewhere that is responsible for manipulating routes, how can I put DynamicRouter in scope? I'm learning about _G right now, but my php background tells me this is very likely not the way to go.

Really rough example

web.moon

DynamicRouter = require("lib.DynamicRouter")!

class App extends lapis.Application
  @include "apps.router"
  default_route: =>
    DynamicRouter\handleRequest @

apps.router

lapis = require "lapis"
class router extends lapis.Application
  path: "/blah"
  [addRoute: "/addroute"]: =>
    somehow_call_DynamicRouter\addRoute(@req)
lordnynex commented 10 years ago

Also, while I'm bothering you on github, any chance of a lapis google group?