Ralf
Ralf

Reputation: 2632

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!

Upvotes: 7

Views: 1747

Answers (1)

Dogbert
Dogbert

Reputation: 222040

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.

Upvotes: 11

Related Questions