I try to build a very simple REST API. It does not include a database or models.
Here's my router:
defmodule Zentonies.Router do
use Zentonies.Web, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug :put_secure_browser_headers
end
pipeline :api do
plug :accepts, ["json"]
end
scope "/v1/events/", Zentonies do
pipe_through :api
post "/call", PageController, :call
end
end
Here is the Controller:
defmodule Zentonies.PageController do
require Logger
import Joken
use Zentonies.Web, :controller
def index(conn, _params) do
render conn, "index.html"
end
def call(conn, params) do
Logger.debug inspect(params)
conn
|> put_status(200)
|> text("Response.")
end
end
Now, if I HTTP POST to this endpoint, inspect(params)
does not return the JSON body of my POST request. Instead it returns the :call
.
Any help is greatly appreciated!
Each of these actions takes two parameters, which will be provided by Phoenix behind the scenes. The first parameter is always conn, a struct which holds information about the request such as the host, path elements, port, query string, and much more. conn comes to Phoenix via Elixir's Plug middleware framework.
The first parameter is always conn, a struct which holds information about the request such as the host, path elements, port, query string, and much more. conn comes to Phoenix via Elixir's Plug middleware framework. More detailed information about conn can be found in the Plug.Conn documentation. The second parameter is params.
Their functions — called actions — are invoked from the router in response to HTTP requests. The actions, in turn, gather all the necessary data and perform all the necessary steps before invoking the view layer to render a template or returning a JSON response. Phoenix controllers also build on the Plug package, and are themselves plugs.
The simplest is to render some plain text using the text/2 function which Phoenix provides. For example, let's rewrite the show action from HelloController to return text instead. For that, we could do the following. Now /hello/Frank in your browser should display From messenger Frank as plain text without any HTML.
A call/2
function is defined by Phoenix for its own use to dispatch to the correct action in every Phoenix Controller. By creating a function with that name you're overriding the builtin functionality. You'll have to use a different name for the action. Check out the section "Controllers are plugs" in the documentation of Phoenix.Controller.Pipeline
:
Controllers are plugs
Like routers, controllers are plugs, but they are wired to dispatch to a particular function which is called an action.
For example, the route:
get "/users/:id", UserController, :show
will invoke
UserController
as a plug:UserController.call(conn, :show)
which will trigger the plug pipeline and which will eventually invoke the inner action plug that dispatches to the
show/2
function in theUserController
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With