{"id":13493052,"url":"https://github.com/brandur/sinatra-router","last_synced_at":"2025-04-07T18:13:27.932Z","repository":{"id":6085628,"uuid":"7312328","full_name":"brandur/sinatra-router","owner":"brandur","description":"A tiny vendorable router that makes it easy to try routes from a number of different modular Sinatra applications.","archived":false,"fork":false,"pushed_at":"2024-01-27T17:35:49.000Z","size":32,"stargazers_count":60,"open_issues_count":0,"forks_count":9,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-05-14T18:51:25.435Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/brandur.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2012-12-24T23:24:40.000Z","updated_at":"2023-12-20T02:22:11.000Z","dependencies_parsed_at":"2024-01-13T11:51:49.339Z","dependency_job_id":"8482db3e-d593-4970-b151-c2f4343ccd63","html_url":"https://github.com/brandur/sinatra-router","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brandur%2Fsinatra-router","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brandur%2Fsinatra-router/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brandur%2Fsinatra-router/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brandur%2Fsinatra-router/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/brandur","download_url":"https://codeload.github.com/brandur/sinatra-router/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247704571,"owners_count":20982298,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T19:01:11.766Z","updated_at":"2025-04-07T18:13:27.914Z","avatar_url":"https://github.com/brandur.png","language":"Ruby","funding_links":[],"categories":["Routers","Middlewares"],"sub_categories":[],"readme":"# sinatra-router [![Build Status](https://github.com/brandur/sinatra-router/workflows/sinatra-router%20CI/badge.svg)](https://github.com/brandur/sinatra-router/actions)\n\nA tiny vendorable router that makes it easy to try routes from a number of different modular Sinatra applications.\n\nThe motivation behind the project is to provide an easy way of composing a larger application that's been split out into a number of discrete Sinatra apps for purposes of code modularity and isolation.\n\nIn your `Gemfile`:\n\n``` ruby\ngem 'sinatra-router'\n```\n\nNow as part of a builder or rackup (i.e. `config.ru`):\n\n``` ruby\nrequire \"sinatra\"\nrequire \"sinatra/router\"\n\nmodule API\n  class Apps \u003c Sinatra::Base\n    get \"/apps\" do\n      200\n    end\n  end\n\n  class Users \u003c Sinatra::Base\n    get \"/users\" do\n      200\n    end\n  end\nend\n\n# config.ru\nrun Sinatra::Router.new do\n  mount API::Apps     # /apps\n  mount API::Users    # /users\nend\n```\n\nOr mount it as middleware:\n\n``` ruby\nuse Sinatra::Router do\n  mount API::Apps\n  mount API::Users\nend\nrun Sinatra::Application\n```\n\n### Why not just mount Sinatra apps as middleware?\n\nAn alternative is to just mount Sinatra apps as middleware, which is supported by Sinatra out of the box:\n\n``` ruby\nrun Rack::Builder.new do\n  use API::Apps\n  use API::Users\nend\n```\n\nThis does get you most of the way there, but may have undesirable side effects. For example, a request always gets passed through each middleware, whether that middleware can handle the route or not. So `before` filters in all your apps will be run until one app in the stack successfully handles the request. This can make it somewhat more difficult to modularize your app.\n\n## Conditional Routing\n\nAdd routing conditions with arguments or blocks:\n\n``` ruby\nrun Sinatra::Router.new do\n  with_conditions(lambda { |e| e[\"HTTP_X_VERSION\"] == \"2\" }) do\n    mount API::V2::Apps\n    mount API::V2::Users\n  end\n\n  mount API::V1::Users, lambda { |e| e[\"HTTP_X_VERSION\"] == \"1\" }\nend\n```\n\nOr extend the router class to create your own concise DSL:\n\n``` ruby\nmodule API\n  class Router \u003c Sinatra::Router\n    def version(version, \u0026block)\n      condition = lambda { |e| version.to_s == e[\"HTTP_X_VERSION\"] }\n      if block\n        with_conditions(condition, \u0026block)\n      else\n        condition\n      end\n    end\n  end\nend\n\n# config.ru\nrun API::Router do\n  version 2 do\n    mount API::V2::Apps\n    mount API::V2::Users\n  end\n\n  mount API::V1::Users, version(1)\nend\n```\n\n## Passing and X-Cascade\n\nSinatra and sinatra-router support Rack's `X-Cascade` standard so that modules are able to transparently pass from one to the other as if they were part of the same application:\n\n``` ruby\nmodule API\n  module V1\n    class Apps \u003c Sinatra::Base\n      get \"/apps\" do\n        # drops through to AppsV2 GET / unless request is version 1\n        pass unless version == 1\n        200\n      end\n    end\n  end\n\n  module V2\n    class Apps \u003c Sinatra::Base\n      get \"/apps\" do\n        200\n      end\n    end\n  end\nend\n\n# config.ru\nrun Sinatra::Router.new do\n  mount API::V1::Apps\n  mount API::V2::Apps\nend\n```\n\n## Development\n\nRun the tests:\n\n``` bash\nbundle exec ruby test/sinatra/router_test.rb\n```\n\n## Release\n\n1. Update the version in `sinatra-router.gemspec` as appropriate for [semantic\n   versioning](http://semver.org) and add details to `CHANGELOG`.\n2. Run the `release` task:\n\n    ```\n    bundle exec rake release\n    ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrandur%2Fsinatra-router","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbrandur%2Fsinatra-router","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrandur%2Fsinatra-router/lists"}