Defines the Phoenix router. A router is the heart of a Phoenix application. It has three main responsibilities: * It defines a plug pipeline responsible for handling upcoming requests and dispatching those requests to controllers and other plugs. * It hosts configuration for the router and related entities (like plugs). * It provides a wrapper for starting and stopping the router in a specific web server. We will explore those responsibilities next. ## Routing The router provides a set of macros for generating routes that dispatch to specific controllers and actions. Those macros are named after HTTP verbs. For example: defmodule MyApp.Router do use Phoenix.Router get "/pages/:page", PageController, :show end The `get/3` macro above accepts a request of format "/pages/VALUE" and dispatches it to the show action in the `PageController`. Phoenix's router is extremely efficient, as it relies on Elixir pattern matching for matching routes and serving requests. ### Helpers Phoenix automatically generates a module `Helpers` inside your router which contains named helpers to help developers generate and keep their routes up to date. Helpers are automatically generated based on the controller name. For example, the route: get "/pages/:page", PageController, :show will generate a named helper: MyApp.Router.Helpers.page_path(:show, "hello") "/pages/hello" MyApp.Router.Helpers.page_path(:show, "hello", some: "query") "/pages/hello?some=query" The named helper can also be customized with the `:as` option. Given the route: get "/pages/:page", PageController, :show, as: :special_page the named helper will be: MyApp.Router.Helpers.special_page_path(:show, "hello") "/pages/hello" ### Scopes and Resources The router also supports scoping of routes: scope "/api/v1", as: :api_v1 do get "/pages/:id", PageController, :show end For example, the route above will match on the path `"/api/v1/pages/:id" and the named route will be `api_v1_page_path`, as expected from the values given to `scope/2` option. Phoenix also provides a `resources/4` macro that allows developers to generate "RESTful" routes to a given resource: defmodule MyApp.Router do use Phoenix.Router pipe_through :browser resources "/pages", PageController, only: [:show] resources "/users", UserController, except: [:destroy] end Finally, Phoenix ships with a `mix phoenix.routes` task that nicely formats all routes in a given router. We can use it to verify all routes included in the router above: $ mix phoenix.routes page_path GET /pages/:id PageController.show/2 user_path GET /users UserController.index/2 user_path GET /users/:id/edit UserController.edit/2 user_path GET /users/new UserController.new/2 user_path GET /users/:id UserController.show/2 user_path POST /users UserController.create/2 user_path PATCH /users/:id UserController.update/2 PUT /users/:id UserController.update/2 One can also pass a router explicitly as an argument to the task: $ mix phoenix.routes MyApp.Router Check `scope/2` and `resources/4` for more information. ## Pipelines and plugs Once a request arrives to the Phoenix router, it performs a series of transformations through pipelines until the request is dispatched to a desired end-point. Such transformations are defined via plugs, as defined in the [Plug](http://github.com/elixir-lang/plug) specification. Once a pipeline is defined, it can be piped through per scope. For example: defmodule MyApp.Router do use Phoenix.Router pipeline :browser do plug :fetch_session plug :accepts, ~w(html json) end scope "/" do pipe_through :browser # browser related routes and resources end end `Phoenix.Router` imports functions from both `Plug.Conn` and `Phoenix.Controller` to help define plugs. In the example above, `fetch_session/2` comes from `Plug.Conn` while `accepts/2` comes from `Phoenix.Controller`. By default, Phoenix ships with one pipeline, called `:before`, that is always invoked before any route matches. All other pipelines are invoked only after a specific route matches, but before the route is dispatched to. ### :before pipeline Those are the plugs in the `:before` pipeline in the order they are defined. How each plug is configured is defined in a later sections. * `Plug.Static` - serves static assets. Since this plug comes before the router, serving of static assets is not logged * `Plug.Logger` - logs incoming requests * `Plug.Parsers` - parses the request body when a known parser is available. By default parsers urlencoded, multipart and json (with poison). The request body is left untouched when the request content-type cannot be parsed * `Plug.MethodOverride` - converts the request method to `PUT`, `PATCH` or `DELETE` for `POST` requests with a valid `_method` parameter * `Plug.Head` - converts `HEAD` requests to `GET` requests and strips the response body * `Plug.Session` - a plug that sets up session management. Note that `fetch_session/2` must still be explicitly called before using the session as this plug just sets up how the session is fetched * `Phoenix.CodeReloader` - a plug that enables code reloading for all entries in the `web` directory. It is configured directly in the Phoenix application ### Customizing pipelines You can define new pipelines at any moment with the `pipeline/2` macro: pipeline :api do plug :token_authentication end And then in a scope (or at root): pipe_through [:api] ## Router configuration All routers are configured directly in the Phoenix application environment. For example: config :phoenix, YourApp.Router, secret_key_base: "kjoy3o1zeidquwy1398juxzldjlksahdk3" Phoenix configuration is split in two categories. Compile-time configuration means the configuration is read during compilation and changing it at runtime has no effect. Most of the compile-time configuration is related to pipelines and plugs. On the other hand, runtime configuration is accessed during or after your application is started and can be read through the `config/2` function: YourApp.Router.config(:port) YourApp.Router.config(:some_config, :default_value) ### Compile-time * `:session` - configures the `Plug.Session` plug. Defaults to `false` but can be set to a keyword list of options as defined in `Plug.Session`. For example: config :phoenix, YourApp.Router, session: [store: :cookie, key: "_your_app_key"] * `:parsers` - sets up the request parsers. Accepts a set of options as defined by `Plug.Parsers`. If parsers are disabled, parameters won't be explicitly fetched before matching a route and functionality dependent on parameters, like the `Plug.MethodOverride`, will be disabled too. Defaults to: [pass: ["*/*"], json_decoder: Poison, parsers: [:urlencoded, :multipart, :json]] * `:static` - sets up static assets serving. Accepts a set of options as defined by `Plug.Static`. Defaults to: [at: "/", from: Mix.Project.config[:app]] * `:debug_errors` - when true, uses `Plug.Debugger` functionality for debugging failures in the application. Recomended to be set to true only in development as it allows listing of the application source code during debugging. Defaults to false. * `:render_errors` - a module representing a view to render templates whenever there is a failure in the application. For example, if the application crashes with a 500 error during a HTML request, `render("500.html", assigns)` will be called in the view given to `:render_errors`. The default view is `MyApp.ErrorsView`. ### Runtime * `:http` - the configuration for the http server. Currently uses cowboy and accepts all options as defined by `Plug.Adapters.Cowboy`. Defaults to false. * `:https` - the configuration for the https server. Currently uses cowboy and accepts all options as defined by `Plug.Adapters.Cowboy`. Defaults to false. * `:secret_key_base` - a secret key used as base to generate secrets to encode cookies, session and friends. Defaults to nil as it must be set per application. * `:url` - configuration for generating URLs throughout the app. Accepts the host, scheme and port. Defaults to: [host: "localhost"] ## Web server Starting a router as part of a web server can be done by invoking `YourApp.Router.start/0`. Stopping the router is done with `YourApp.Router.stop/0`. The web server is configured with the `:http` and `:https` options defined above.