Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

params does not contain POST Body in Elixir / Phoenix

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!

like image 646
Ralf Avatar asked Aug 08 '16 14:08

Ralf


People also ask

What are the two parameters of a request in Phoenix?

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.

What is the difference between Conn and params?

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.

How do actions work in Phoenix?

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.

How to render plain text from Phoenix controller without any HTML?

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.


1 Answers

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 the UserController.

like image 57
Dogbert Avatar answered Oct 09 '22 21:10

Dogbert