{"action":"created","issue":{"url":"https://api.github.com/repos/finagle/finch/issues/334","labels_url":"https://api.github.com/repos/finagle/finch/issues/334/labels{/name}","comments_url":"https://api.github.com/repos/finagle/finch/issues/334/comments","events_url":"https://api.github.com/repos/finagle/finch/issues/334/events","html_url":"https://github.com/finagle/finch/pull/334","id":91850091,"number":334,"title":"Compose Router and RequestReader","user":{"login":"vkostyukov","id":1098539,"avatar_url":"https://avatars.githubusercontent.com/u/1098539?v=3","gravatar_id":"","url":"https://api.github.com/users/vkostyukov","html_url":"https://github.com/vkostyukov","followers_url":"https://api.github.com/users/vkostyukov/followers","following_url":"https://api.github.com/users/vkostyukov/following{/other_user}","gists_url":"https://api.github.com/users/vkostyukov/gists{/gist_id}","starred_url":"https://api.github.com/users/vkostyukov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vkostyukov/subscriptions","organizations_url":"https://api.github.com/users/vkostyukov/orgs","repos_url":"https://api.github.com/users/vkostyukov/repos","events_url":"https://api.github.com/users/vkostyukov/events{/privacy}","received_events_url":"https://api.github.com/users/vkostyukov/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-06-29T16:28:31Z","updated_at":"2015-06-29T16:42:42Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/finagle/finch/pulls/334","html_url":"https://github.com/finagle/finch/pull/334","diff_url":"https://github.com/finagle/finch/pull/334.diff","patch_url":"https://github.com/finagle/finch/pull/334.patch"},"body":"This is the initial attempt tp solve #232. While it requires some polish it's ready to be reviewed.\r\n\r\nThe change is pretty local, it doesn't really touch the user-facing API except for one (pretty major) thing: I had to give up on greedy routers, since otherwise it would require evaluating two futures. So, this PR also addresses #327.\r\n\r\nWith this PR it's possible to compile:\r\n\r\n```scala\r\nval putUser: Router[User] = \r\n  get(\"users\" / int ? (param(\"name\") :: param(\"age\")) /> { (id, name, age) =>\r\n    User(id, name, age)\r\n  }\r\n```\r\n\r\nI would appreciate any ideas on the following topics:\r\n\r\n1. Is there a better name for `?`?\r\n2. How routers can be both lazy and greedy?\r\n3. How can we move some logic from `Router` to `Router.Output` (with adding new functions like `flatMap`, etc)?\r\n"},"comment":{"url":"https://api.github.com/repos/finagle/finch/issues/comments/116755373","html_url":"https://github.com/finagle/finch/pull/334#issuecomment-116755373","issue_url":"https://api.github.com/repos/finagle/finch/issues/334","id":116755373,"user":{"login":"travisbrown","id":316049,"avatar_url":"https://avatars.githubusercontent.com/u/316049?v=3","gravatar_id":"","url":"https://api.github.com/users/travisbrown","html_url":"https://github.com/travisbrown","followers_url":"https://api.github.com/users/travisbrown/followers","following_url":"https://api.github.com/users/travisbrown/following{/other_user}","gists_url":"https://api.github.com/users/travisbrown/gists{/gist_id}","starred_url":"https://api.github.com/users/travisbrown/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/travisbrown/subscriptions","organizations_url":"https://api.github.com/users/travisbrown/orgs","repos_url":"https://api.github.com/users/travisbrown/repos","events_url":"https://api.github.com/users/travisbrown/events{/privacy}","received_events_url":"https://api.github.com/users/travisbrown/received_events","type":"User","site_admin":false},"created_at":"2015-06-29T16:42:42Z","updated_at":"2015-06-29T16:42:42Z","body":"I'm still hesitant to use `Future` to represent the success or failure of the match. It seems like what we really want is a `Path => Option[Path]` transition that returns the remainder in the case of a match, and some result `A` that gets evaluated if we both match and decide to use this route—i.e. something pretty similar to the original API, except that `Path => Option[(Path, A)]` isn't lazy enough about `A`."}}