{"action":"created","comment":{"url":"https://api.github.com/repos/mxenabled/action_subscriber/pulls/comments/65339935","id":65339935,"diff_hunk":"@@ -2,6 +2,7 @@ module ActionSubscriber\n   class Router\n     def self.draw_routes(&block)\n       router = self.new\n+      ::ActiveSupport.run_load_hooks(:action_subscriber_routes, router)","path":"lib/action_subscriber/router.rb","position":4,"original_position":4,"commit_id":"cfe42abd24dc05eca7ef7407468be6cfd5c6863c","original_commit_id":"cfe42abd24dc05eca7ef7407468be6cfd5c6863c","user":{"login":"jasonayre","id":155084,"avatar_url":"https://avatars.githubusercontent.com/u/155084?v=3","gravatar_id":"","url":"https://api.github.com/users/jasonayre","html_url":"https://github.com/jasonayre","followers_url":"https://api.github.com/users/jasonayre/followers","following_url":"https://api.github.com/users/jasonayre/following{/other_user}","gists_url":"https://api.github.com/users/jasonayre/gists{/gist_id}","starred_url":"https://api.github.com/users/jasonayre/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jasonayre/subscriptions","organizations_url":"https://api.github.com/users/jasonayre/orgs","repos_url":"https://api.github.com/users/jasonayre/repos","events_url":"https://api.github.com/users/jasonayre/events{/privacy}","received_events_url":"https://api.github.com/users/jasonayre/received_events","type":"User","site_admin":false},"body":"Sure, this was added more for the ability of extensibility, i.e. in my gem which uses a middleware stack which adds a certain behavior, I can go\r\n\r\n``` ruby\r\n::ActionSubscriber.on_load(: action_subscriber_routes) do\r\n  stack :whatever do\r\n    use A\r\n    use B\r\n  end\r\nend\r\n```\r\n\r\netc. But the implementation could be changed if the router is removed from the stack and stacks were composable, i.e.\r\n\r\n``` ruby\r\n  class MyPluginsMiddlewareStack < ActionSubscriber::MiddlewareStack\r\n    use A\r\n    use B\r\n  end\r\n\r\n  ActionSubscriber.config.middleware_stacks << MyPluginsMiddlewareStack\r\n```\r\n\r\nFor example\r\n\r\n  ","created_at":"2016-06-01T10:55:04Z","updated_at":"2016-06-01T10:55:04Z","html_url":"https://github.com/mxenabled/action_subscriber/pull/65#discussion_r65339935","pull_request_url":"https://api.github.com/repos/mxenabled/action_subscriber/pulls/65","_links":{"self":{"href":"https://api.github.com/repos/mxenabled/action_subscriber/pulls/comments/65339935"},"html":{"href":"https://github.com/mxenabled/action_subscriber/pull/65#discussion_r65339935"},"pull_request":{"href":"https://api.github.com/repos/mxenabled/action_subscriber/pulls/65"}}},"pull_request":{"url":"https://api.github.com/repos/mxenabled/action_subscriber/pulls/65","id":70136824,"html_url":"https://github.com/mxenabled/action_subscriber/pull/65","diff_url":"https://github.com/mxenabled/action_subscriber/pull/65.diff","patch_url":"https://github.com/mxenabled/action_subscriber/pull/65.patch","issue_url":"https://api.github.com/repos/mxenabled/action_subscriber/issues/65","number":65,"state":"open","locked":false,"title":"Add support for per route middleware stacks","user":{"login":"jasonayre","id":155084,"avatar_url":"https://avatars.githubusercontent.com/u/155084?v=3","gravatar_id":"","url":"https://api.github.com/users/jasonayre","html_url":"https://github.com/jasonayre","followers_url":"https://api.github.com/users/jasonayre/followers","following_url":"https://api.github.com/users/jasonayre/following{/other_user}","gists_url":"https://api.github.com/users/jasonayre/gists{/gist_id}","starred_url":"https://api.github.com/users/jasonayre/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jasonayre/subscriptions","organizations_url":"https://api.github.com/users/jasonayre/orgs","repos_url":"https://api.github.com/users/jasonayre/repos","events_url":"https://api.github.com/users/jasonayre/events{/privacy}","received_events_url":"https://api.github.com/users/jasonayre/received_events","type":"User","site_admin":false},"body":"This adds support for setting up a middleware stack while defining routes, and using that middleware stack for a particular route.\r\n\r\nAs I began looking at ActionSubscriber to replace my existing async pubsub library, I came across the routing / middleware, which seems really cool. Problem is, middleware wouldn't really get me much in it's current form with what I'm looking to do as it's global. With this PR, each route can have it's own set of middleware, which is forked from `ActionSubscriber.config.middleware`. - I borrowed the idea from the Phoenix router and it's pipeline/plugs feature. http://www.phoenixframework.org/docs/routing\r\n\r\nUse case example: parsing payload and to lookup the resource, and pass it along in it's loaded form. (while allowing non resourceful types of messages to be sent through other areas).\r\n\r\n``` ruby\r\n#assume you publish message in an ActiveRecord callback with the following format:\r\n{\r\n  :resource => self.attributes,\r\n  :changes => self.changes,\r\n  :resource_type => self.class.base_class.name\r\n}\r\n\r\nclass HasChanges\r\n  def initialize(app)\r\n    @app = app\r\n  end\r\n  \r\n  def call(env)\r\n    env[\"changes\"] = Changes.new(env[\"payload\"][\"changes\"])\r\n    @app.call(env)\r\n  end\r\nend\r\n\r\nclass HasResource\r\n  def initialize(app)\r\n    @app = app\r\n  end\r\n  \r\n  def call(env)\r\n    attributes = env[\"payload\"][\"resource\"]\r\n\tmodel = env[\"payload\"][\"resource_type\"].constantize\r\n    env[\"resource\"] = model.find(attributes[\"id\"])\r\n    @app.call(env)\r\n  end\r\nend\r\n\r\n::ActionSubscriber.draw_routes do\r\n  stack :resourceful do\r\n    use HasChanges\r\n    use HasResource\r\n  end\r\n\r\n  route ::Census::SurveysSubscriber, :updated, :durable => true, :exchange => :events, :stack => :resourceful\r\n  route ::Census::SurveysSubscriber, :created, :durable => true, :exchange => :events, :stack => :resourceful\r\nend\r\n```\r\n\r\nThe main changes are that the middleware for the particular route gets passed in to the env, which will be executed rather than ActionSubscriber.config.middleware (but that's not a requirement if it can be looked up another way). Also the middleware stacks are now duplicated from the existing default middleware so that each route has it's own. The last large change is that I added hash accessors to env object so it behaves more like rack, which makes what you can do via the middlewares much more powerful. Tested and working with my local app except march hare/jruby.\r\n","created_at":"2016-05-15T23:17:49Z","updated_at":"2016-06-01T10:55:04Z","closed_at":null,"merged_at":null,"merge_commit_sha":"9646709a83f825a6905cc494c8c94c8bc55e5749","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/mxenabled/action_subscriber/pulls/65/commits","review_comments_url":"https://api.github.com/repos/mxenabled/action_subscriber/pulls/65/comments","review_comment_url":"https://api.github.com/repos/mxenabled/action_subscriber/pulls/comments{/number}","comments_url":"https://api.github.com/repos/mxenabled/action_subscriber/issues/65/comments","statuses_url":"https://api.github.com/repos/mxenabled/action_subscriber/statuses/cfe42abd24dc05eca7ef7407468be6cfd5c6863c","head":{"label":"jasonayre:master","ref":"master","sha":"cfe42abd24dc05eca7ef7407468be6cfd5c6863c","user":{"login":"jasonayre","id":155084,"avatar_url":"https://avatars.githubusercontent.com/u/155084?v=3","gravatar_id":"","url":"https://api.github.com/users/jasonayre","html_url":"https://github.com/jasonayre","followers_url":"https://api.github.com/users/jasonayre/followers","following_url":"https://api.github.com/users/jasonayre/following{/other_user}","gists_url":"https://api.github.com/users/jasonayre/gists{/gist_id}","starred_url":"https://api.github.com/users/jasonayre/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jasonayre/subscriptions","organizations_url":"https://api.github.com/users/jasonayre/orgs","repos_url":"https://api.github.com/users/jasonayre/repos","events_url":"https://api.github.com/users/jasonayre/events{/privacy}","received_events_url":"https://api.github.com/users/jasonayre/received_events","type":"User","site_admin":false},"repo":{"id":58774208,"name":"action_subscriber","full_name":"jasonayre/action_subscriber","owner":{"login":"jasonayre","id":155084,"avatar_url":"https://avatars.githubusercontent.com/u/155084?v=3","gravatar_id":"","url":"https://api.github.com/users/jasonayre","html_url":"https://github.com/jasonayre","followers_url":"https://api.github.com/users/jasonayre/followers","following_url":"https://api.github.com/users/jasonayre/following{/other_user}","gists_url":"https://api.github.com/users/jasonayre/gists{/gist_id}","starred_url":"https://api.github.com/users/jasonayre/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jasonayre/subscriptions","organizations_url":"https://api.github.com/users/jasonayre/orgs","repos_url":"https://api.github.com/users/jasonayre/repos","events_url":"https://api.github.com/users/jasonayre/events{/privacy}","received_events_url":"https://api.github.com/users/jasonayre/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jasonayre/action_subscriber","description":"Easily subscribe to RabbitMQ messages from your Rails application","fork":true,"url":"https://api.github.com/repos/jasonayre/action_subscriber","forks_url":"https://api.github.com/repos/jasonayre/action_subscriber/forks","keys_url":"https://api.github.com/repos/jasonayre/action_subscriber/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jasonayre/action_subscriber/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jasonayre/action_subscriber/teams","hooks_url":"https://api.github.com/repos/jasonayre/action_subscriber/hooks","issue_events_url":"https://api.github.com/repos/jasonayre/action_subscriber/issues/events{/number}","events_url":"https://api.github.com/repos/jasonayre/action_subscriber/events","assignees_url":"https://api.github.com/repos/jasonayre/action_subscriber/assignees{/user}","branches_url":"https://api.github.com/repos/jasonayre/action_subscriber/branches{/branch}","tags_url":"https://api.github.com/repos/jasonayre/action_subscriber/tags","blobs_url":"https://api.github.com/repos/jasonayre/action_subscriber/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jasonayre/action_subscriber/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jasonayre/action_subscriber/git/refs{/sha}","trees_url":"https://api.github.com/repos/jasonayre/action_subscriber/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jasonayre/action_subscriber/statuses/{sha}","languages_url":"https://api.github.com/repos/jasonayre/action_subscriber/languages","stargazers_url":"https://api.github.com/repos/jasonayre/action_subscriber/stargazers","contributors_url":"https://api.github.com/repos/jasonayre/action_subscriber/contributors","subscribers_url":"https://api.github.com/repos/jasonayre/action_subscriber/subscribers","subscription_url":"https://api.github.com/repos/jasonayre/action_subscriber/subscription","commits_url":"https://api.github.com/repos/jasonayre/action_subscriber/commits{/sha}","git_commits_url":"https://api.github.com/repos/jasonayre/action_subscriber/git/commits{/sha}","comments_url":"https://api.github.com/repos/jasonayre/action_subscriber/comments{/number}","issue_comment_url":"https://api.github.com/repos/jasonayre/action_subscriber/issues/comments{/number}","contents_url":"https://api.github.com/repos/jasonayre/action_subscriber/contents/{+path}","compare_url":"https://api.github.com/repos/jasonayre/action_subscriber/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jasonayre/action_subscriber/merges","archive_url":"https://api.github.com/repos/jasonayre/action_subscriber/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jasonayre/action_subscriber/downloads","issues_url":"https://api.github.com/repos/jasonayre/action_subscriber/issues{/number}","pulls_url":"https://api.github.com/repos/jasonayre/action_subscriber/pulls{/number}","milestones_url":"https://api.github.com/repos/jasonayre/action_subscriber/milestones{/number}","notifications_url":"https://api.github.com/repos/jasonayre/action_subscriber/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jasonayre/action_subscriber/labels{/name}","releases_url":"https://api.github.com/repos/jasonayre/action_subscriber/releases{/id}","deployments_url":"https://api.github.com/repos/jasonayre/action_subscriber/deployments","created_at":"2016-05-13T21:43:27Z","updated_at":"2016-05-13T21:43:28Z","pushed_at":"2016-05-17T00:07:10Z","git_url":"git://github.com/jasonayre/action_subscriber.git","ssh_url":"git@github.com:jasonayre/action_subscriber.git","clone_url":"https://github.com/jasonayre/action_subscriber.git","svn_url":"https://github.com/jasonayre/action_subscriber","homepage":null,"size":334,"stargazers_count":0,"watchers_count":0,"language":"Ruby","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"mxenabled:master","ref":"master","sha":"4d12140fddc49bbec3f3c38043a706fd2888b77d","user":{"login":"mxenabled","id":991323,"avatar_url":"https://avatars.githubusercontent.com/u/991323?v=3","gravatar_id":"","url":"https://api.github.com/users/mxenabled","html_url":"https://github.com/mxenabled","followers_url":"https://api.github.com/users/mxenabled/followers","following_url":"https://api.github.com/users/mxenabled/following{/other_user}","gists_url":"https://api.github.com/users/mxenabled/gists{/gist_id}","starred_url":"https://api.github.com/users/mxenabled/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mxenabled/subscriptions","organizations_url":"https://api.github.com/users/mxenabled/orgs","repos_url":"https://api.github.com/users/mxenabled/repos","events_url":"https://api.github.com/users/mxenabled/events{/privacy}","received_events_url":"https://api.github.com/users/mxenabled/received_events","type":"Organization","site_admin":false},"repo":{"id":26502562,"name":"action_subscriber","full_name":"mxenabled/action_subscriber","owner":{"login":"mxenabled","id":991323,"avatar_url":"https://avatars.githubusercontent.com/u/991323?v=3","gravatar_id":"","url":"https://api.github.com/users/mxenabled","html_url":"https://github.com/mxenabled","followers_url":"https://api.github.com/users/mxenabled/followers","following_url":"https://api.github.com/users/mxenabled/following{/other_user}","gists_url":"https://api.github.com/users/mxenabled/gists{/gist_id}","starred_url":"https://api.github.com/users/mxenabled/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mxenabled/subscriptions","organizations_url":"https://api.github.com/users/mxenabled/orgs","repos_url":"https://api.github.com/users/mxenabled/repos","events_url":"https://api.github.com/users/mxenabled/events{/privacy}","received_events_url":"https://api.github.com/users/mxenabled/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mxenabled/action_subscriber","description":"Easily subscribe to RabbitMQ messages from your Rails application","fork":false,"url":"https://api.github.com/repos/mxenabled/action_subscriber","forks_url":"https://api.github.com/repos/mxenabled/action_subscriber/forks","keys_url":"https://api.github.com/repos/mxenabled/action_subscriber/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mxenabled/action_subscriber/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mxenabled/action_subscriber/teams","hooks_url":"https://api.github.com/repos/mxenabled/action_subscriber/hooks","issue_events_url":"https://api.github.com/repos/mxenabled/action_subscriber/issues/events{/number}","events_url":"https://api.github.com/repos/mxenabled/action_subscriber/events","assignees_url":"https://api.github.com/repos/mxenabled/action_subscriber/assignees{/user}","branches_url":"https://api.github.com/repos/mxenabled/action_subscriber/branches{/branch}","tags_url":"https://api.github.com/repos/mxenabled/action_subscriber/tags","blobs_url":"https://api.github.com/repos/mxenabled/action_subscriber/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mxenabled/action_subscriber/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mxenabled/action_subscriber/git/refs{/sha}","trees_url":"https://api.github.com/repos/mxenabled/action_subscriber/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mxenabled/action_subscriber/statuses/{sha}","languages_url":"https://api.github.com/repos/mxenabled/action_subscriber/languages","stargazers_url":"https://api.github.com/repos/mxenabled/action_subscriber/stargazers","contributors_url":"https://api.github.com/repos/mxenabled/action_subscriber/contributors","subscribers_url":"https://api.github.com/repos/mxenabled/action_subscriber/subscribers","subscription_url":"https://api.github.com/repos/mxenabled/action_subscriber/subscription","commits_url":"https://api.github.com/repos/mxenabled/action_subscriber/commits{/sha}","git_commits_url":"https://api.github.com/repos/mxenabled/action_subscriber/git/commits{/sha}","comments_url":"https://api.github.com/repos/mxenabled/action_subscriber/comments{/number}","issue_comment_url":"https://api.github.com/repos/mxenabled/action_subscriber/issues/comments{/number}","contents_url":"https://api.github.com/repos/mxenabled/action_subscriber/contents/{+path}","compare_url":"https://api.github.com/repos/mxenabled/action_subscriber/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mxenabled/action_subscriber/merges","archive_url":"https://api.github.com/repos/mxenabled/action_subscriber/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mxenabled/action_subscriber/downloads","issues_url":"https://api.github.com/repos/mxenabled/action_subscriber/issues{/number}","pulls_url":"https://api.github.com/repos/mxenabled/action_subscriber/pulls{/number}","milestones_url":"https://api.github.com/repos/mxenabled/action_subscriber/milestones{/number}","notifications_url":"https://api.github.com/repos/mxenabled/action_subscriber/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mxenabled/action_subscriber/labels{/name}","releases_url":"https://api.github.com/repos/mxenabled/action_subscriber/releases{/id}","deployments_url":"https://api.github.com/repos/mxenabled/action_subscriber/deployments","created_at":"2014-11-11T20:17:08Z","updated_at":"2016-05-14T23:08:10Z","pushed_at":"2016-05-17T00:07:10Z","git_url":"git://github.com/mxenabled/action_subscriber.git","ssh_url":"git@github.com:mxenabled/action_subscriber.git","clone_url":"https://github.com/mxenabled/action_subscriber.git","svn_url":"https://github.com/mxenabled/action_subscriber","homepage":null,"size":327,"stargazers_count":11,"watchers_count":11,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":9,"mirror_url":null,"open_issues_count":9,"forks":9,"open_issues":9,"watchers":11,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/mxenabled/action_subscriber/pulls/65"},"html":{"href":"https://github.com/mxenabled/action_subscriber/pull/65"},"issue":{"href":"https://api.github.com/repos/mxenabled/action_subscriber/issues/65"},"comments":{"href":"https://api.github.com/repos/mxenabled/action_subscriber/issues/65/comments"},"review_comments":{"href":"https://api.github.com/repos/mxenabled/action_subscriber/pulls/65/comments"},"review_comment":{"href":"https://api.github.com/repos/mxenabled/action_subscriber/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/mxenabled/action_subscriber/pulls/65/commits"},"statuses":{"href":"https://api.github.com/repos/mxenabled/action_subscriber/statuses/cfe42abd24dc05eca7ef7407468be6cfd5c6863c"}}}}
{"actor":{"display_login":"jasonayre"}}