Skip to content
Permalink
Browse files

## Adding a Route

Our Phoenix endpoint is now listening for inbound HTTP requests, but this doesn’t do us much good if we’re not serving any content!

The first step in serving content from a Phoenix application is to configure our router. A router maps requests sent to a route, or path on your web server, to a specific module and function. That function’s job is to handle the request and return a response.

We can add a route to our application by making a new module, `MinimalWeb.Router`, that uses `Phoenix.Router`:

	defmodule MinimalWeb.Router do
	  use Phoenix.Router
	end

And we can instruct our `MinimalWeb.Endpoint` to use our new router:

	plug(MinimalWeb.Router)

The `Phoenix.Router` module [generates a handful of helpful macros](https://github.com/phoenixframework/phoenix/blob/v1.4/lib/phoenix/router.ex#L216), like [`match`](https://github.com/phoenixframework/phoenix/blob/v1.4/lib/phoenix/router.ex#L433-L435), [`get`, `post`, etc…](https://github.com/phoenixframework/phoenix/blob/v1.4/lib/phoenix/router.ex#L437-L444) and configures itself to a [module-based plug](https://github.com/phoenixframework/phoenix/blob/v1.4/lib/phoenix/router.ex#L288). This is the reason we can seamlessly incorporate it in our endpoint using the `plug` macro.

Now that our router is wired into our endpoint, let’s add a route to our application:

	get("/", MinimalWeb.HomeController, :index)

Here we’re instructing Phoenix to send any HTTP `GET` requests for `/` to the `index/2` function in our `MinimalWeb.HomeController` “controller” module.

Our `MinimalWeb.HomeController` module needs to `use` `Phoenix.Controller` and provide our `MinimalWeb` module as a `:namespace` configuration option:

	defmodule MinimalWeb.HomeController do
	  use Phoenix.Controller, namespace: MinimalWeb
	end

`Phoenix.Controller`, like `Phoenix.Endpoint` and `Phoenix.Router` does quite a bit. It [establishes itself as a plug](https://github.com/phoenixframework/phoenix/blob/v1.4/lib/phoenix/controller/pipeline.ex#L7-L37) and by using [`Phoenix.Controller.Pipeline`](https://github.com/phoenixframework/phoenix/blob/v1.4/lib/phoenix/controller.ex#L168), and it uses the `:namespace` module we provide to do some [automatic layout and view module detection](https://github.com/phoenixframework/phoenix/blob/v1.4/lib/phoenix/controller.ex#L170-L171).

 Because our controller module is essentially a glorified plug, we can expect Phoenix to pass `conn` as the first argument to our specified controller function, and any user-provided parameters as the second argument. Just like any other plug’s `call/2` function, our `index/2` should return our (potentially modified) `conn`:

	def index(conn, _params) do
	  conn
	end

But returning an unmodified `conn` like this is essentially a no-op.

Let’s spice things up a bit and return a simple HTML response to the requester. The simplest way of doing that is to use Phoenix’s built-in `Phoenix.Controller.html/2` function, which takes our `conn` as its first argument, and the HTML we want to send back to the client as the second:

	Phoenix.Controller.html(conn, """
	  <p>Hello.</p>
	""")

If we dig into [`html/2`](https://github.com/phoenixframework/phoenix/blob/v1.4/lib/phoenix/controller.ex#L375-L377), we’ll find that it’s using Plug’s built-in `Plug.Conn.send_resp/3` function:

	Plug.Conn.send_resp(conn, 200, """
	  <p>Hello.</p>
	""")

And ultimately `send_resp/3` is just modifying our `conn` structure directly:

	%{
	  conn
	  | status: 200,
	    resp_body: """
	      <p>Hello.</p>
	    """,
	    state: :set
	}

These three expressions are identical, and we can use whichever one we choose to return our HTML fragment from our controller. For now, we’ll follow best practices and stick with Phoenix’s `html/2` helper function.
  • Loading branch information...
pcorey committed May 8, 2019
1 parent 6e654aa commit 5350b88a121c6c01c3df9ad3345bd8ce350049aa
Showing with 16 additions and 0 deletions.
  1. +9 −0 lib/minimal_web/controllers/home_controller.ex
  2. +2 −0 lib/minimal_web/endpoint.ex
  3. +5 −0 lib/minimal_web/router.ex
@@ -0,0 +1,9 @@
defmodule MinimalWeb.HomeController do
use Phoenix.Controller, namespace: MinimalWeb

def index(conn, _params) do
Phoenix.Controller.html(conn, """
<p>Hello.</p>
""")
end
end
@@ -1,3 +1,5 @@
defmodule MinimalWeb.Endpoint do
use Phoenix.Endpoint, otp_app: :minimal

plug(MinimalWeb.Router)
end
@@ -0,0 +1,5 @@
defmodule MinimalWeb.Router do
use Phoenix.Router

get("/", MinimalWeb.HomeController, :index)
end

0 comments on commit 5350b88

Please sign in to comment.
You can’t perform that action at this time.