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

More extensible routing #22

Open
ch1c0t opened this issue Apr 22, 2015 · 2 comments
Open

More extensible routing #22

ch1c0t opened this issue Apr 22, 2015 · 2 comments

Comments

@ch1c0t
Copy link

ch1c0t commented Apr 22, 2015

Hobbit is by far the most extensible web library I ever seen. There is still, however, a feature which I miss. I would like to have a way to change routing behaviour besides defining routes.

Let me give an example. Currently, the default behaviour of the following app

class App < Hobbit::Base
  get '/before' do
    'before'
  end

  get '/:name' do
    "The name is #{request.params[:name]}"
  end

  get '/after' do
    'after'
  end
end

is to return "The name is after" when /after route is requested. And it seems there is no easy way to make it return "after", without changing the order of route definitions.

Suppose there is a third-party module which provides /before and /:name routes. The question is how can we get the app routes have priority over the module ones? (Of course, we can just include this module at the very end. But still, in a more complex app, it seems beneficial to have a way to set priorities.)

I have started to do some work here, but it would be difficult to proceed until #21 resolved.

@patriciomacadden
Copy link
Owner

I kind of like the idea, but I'd rather do this explicitly (like Sinatra does) by calling a pass method or something alike. Otherwise could be difficult to find certain issues.

Could you try to make an extension instead of modify the codebase?

@ch1c0t
Copy link
Author

ch1c0t commented Apr 23, 2015

Could you try to make an extension instead of modify the codebase?

I probably could, but what I want is very different from what Sinatra's pass does. For that reason I would like to discuss a little bit more(if it does not disturb you).

I provide an implementation of the feature in this branch for illustrative purposes. ( I do not propose to merge it into the master, obviously. )

One can specify a custom router for an app like so:

class App < Hobbit::Base
  router do
    Hobbit::Router.new # Router should be able to take a block,
                       # in which its behaviour can be changed in various ways.
                       # Currently, it does not implemented yet.
  end
end

Users should not be obligated to use Hobbit::Router. On the contrary, they should be allowed to use any object as a router, as long as it complies to the public API of Hobbit::Router:

class App < Hobbit::Base
  router do
    Class.new do
      def add_route(*)
      end

      def route_for(_request)
        Proc.new { 'This string will be returned for any route.' }
      end
    end.new
  end
end

The API of Hobbit::Router(and the whole implementation) is preliminary. Every part of it should be discussed if you like the idea. I would like to draw your attention to the general idea of extracting Router from Base and providing the ability to change routing behaviour completely.

I hope, this time I expressed my wish more clearly. How do you like it?

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