{"title":"Routes","description":"","section":"guides/routing","version":"v1.5","path":"guides/routing/routes","canonical_url":"https://amberframework.org/docs/v1.5/guides/routing/routes","markdown_url":"https://amberframework.org/docs/v1.5/guides/routing/routes.md","inherited":true,"content_markdown":"# Routes\n\nRouting in Amber provides developers a manifest to map application URLs to controller actions. By defining routes, you can separate how your application directs requests and how URLs are structured. Each route creates a real-time web socket handler, and define a series of pipeline transformations for scoping middleware to sets of routes.\n\nA route connects a HTTP request to a function inside a controller. When your Amber application receives an incoming request for: `GET /users/24` it asks the Amber router to find the corresponding controller action to direct the request towards. If the router finds a match, for example `get users/:id, UsersController, :index`, the request will be dispatched to the matching method with the provided parameters, in this case the UsersController.index action with { id: 24 } in the params hash.\n\n## Configuring Routes\n\nRoutes are configured in the `{project_name}/config/routes.cr` file.\n\n```crystal\nAmber::Server.configure do |app|\n  routes :static do\n    # Each route is defined as follow\n    # verb resource : String, controller : Symbol, action : Symbol\n    get \"/*\", StaticController, :index\n  end\nend\n```\n\n## Defining Routes\n\nThe **routes** macro accepts a **pipeline** name and a **scope**. In addition to the pipeline and scope, the routes macro also takes an additional block parameter where you can define routes. All routes defined within a scope's block will make use of the provided pipeline and the URLs will be scoped accordingly.\n\nFor example, let's say you are creating a static website and you want the URL to be displayed as `http://www.mycoolsite.com/page`. To do this, you would setup your routes as follows:\n\n```crystal\n# routes(pipeline, scope)\nroutes :web, \"/page\"\n```\n\nIf you wanted to created a namespace for nesting your URL routes, you can use the scope parameter to do so.\n\n```crystal\nroutes :web, '/v1' do\n  get \"/about\", StaticController, :about\nend\n```\n\nMapping the above route\n\n| Http Method | Path        | Controller       | Action |\n| ----------- | ----------- | ---------------- | ------ |\n| get         | \"/v1/about\" | StaticController | :about |\n\nYour controller action will need to return a string or render a view. If no string or view is rendered your routes configuration will raise an error during compilation.\n\n```crystal\nclass StaticController < ApplicationController\n\t def about\n\t\t \"About my cool page!\"\n\t end\n\n\t # or:\n\n\t def about\n\t\t render(\"about.ecr\")\n\t end\nend\n```\n\n## Resources\n\nThe router supports other macros besides those for HTTP verbs like _get_, _post_, and _put_. The most important among them is `resources`. The `resources` macro is a quick way to setup up resourceful routing for all seven standard actions for a controller in a single line.\n\n{% hint style=\"info\" %}\nIn order to use resourceful routing for a particular controller, your controller _must_ define and implement all seven standard actions: `index`, `edit`, `new`, `show`, `create`, `destroy`, and `update`. If your controller does not implement all seven actions, an error will be raised during compilation.\n{% endhint %}\n\nLet’s add a resource to the `config/routes.cr`\n\n```crystal\nroutes :web do\n  resources \"/posts\", PostsController\nend\n```\n\nThen go to the root of your project, and run `amber routes`\n\nThis will output the standard matrix of HTTP verbs, controller, action, pipeline, scope, and URI pattern.\n\n![Amber Routes Matrix Example](https://raw.githubusercontent.com/amberframework/site-assets/master/images/amber\\_routes.png)\n\n## Scoped Routes\n\nScopes are a way to group routes under a common path prefix and scoped set of pipeline handlers. We might want to do this for admin functionality, APIs, and especially for versioned APIs. Let’s say we have user-generated posts on a site, and that those posts first need to be approved by an admin. The semantics of these resources are quite different, and they might not share the same controller. Scopes enable us to segregate these routes.\n\nThe paths to the user facing reviews would look like a standard resource.\n\n```\n/posts\n/posts/1234\n/posts/1234/edit\n...\n```\n\nBut for the admin console paths could be prefixed with /admin.\n\n```\n/admin/posts\n/admin/posts/1234\n/admin/posts/1234/edit\n...\n```\n\nWe accomplish this with a scoped route that sets a path option to /admin like this one. For now, let’s not nest this scope inside of any other scopes (like the scope \"/\", HelloWeb provides in a new app).\n\n```crystal\n# Not Scoped\nroutes :web do\n  resources \"/posts\", PostsController\nend\n\n# Scoped\nroutes :web, \"/admin\" do\n  resources \"/posts\", AdminPostsController\nend\n```\n\n### Excluding and Including Actions\n\nSometimes you want to use `resources` as a shortcut for defining routes, and with that you don't want to define routes for actions that don't exist yet. `Resources` allow you to pass another argument, `only:` or `except:` to either include actions or exclude them from being generated.\n\nThis will define the following routes:\n\n```crystal\nresources \"/user\", UserController, only: [:index, :show]\nresources \"/user\", UserController, except: [:index, :show]\n```\n\n## Namespaces\n\nNamespaces are a way you can add end-points to your routes that aren't tied to resources but are still collected into deeper nested URI paths.\n\n**Important:** the order you declare your `namespace` and `resource` routes _does_ matter! You must delcare the namespace routes first, then the resource.\n\n```crystal\n# Produces the routes: \n#    GET  /api/my_unique_namespace/my_query_end_point\n#    POST /api/my_unique_namespace/my_query_end_point\nroutes :web, \"/api\" do\n  namespace \"/my_unique_namespace\" do\n    get \"/my_query_end_point\", SomeController, :the_get_action_name\n    post \"/my_query_end_point\", SomeController, :the_post_action_name\n  end\nend\n\n# Produces the normal resources routes & the additional nested routes\n#   GET  /api/users/my_query_end_point\n#   POST /api/users/my_query_end_point\nroutes :web, \"/api\" do\n  \n  # Routes sharing a namespace with `resources` must be declared first\n  namespace \"/users\" do\n    get \"/my_query_end_point\", UsersController, :the_get_action_name\n    post \"/my_query_end_point\", UsersController, :the_post_action_name\n  end\n  \n  # This must come after any namespace routes that are not part of the resource\n  resources \"/users\", UsersController\nend\n    \n```"}