Params in the URL and body -- how does Phoenix handle them together?

If I have a post route which an argument:

  post /my_post_route/:my_param1, MyController.my_post_handler

How would get the post params from its body?

      def my_post_handler(conn, %{"my_param" =>my_param} = params) do
          # ??? how to get "params"   from its body?

In other words, how does Phoenix distinguish between params in the url and params in the body for POST requests?

2 Likes

You can use body_params from conn, I think.

https://hexdocs.pm/plug/Plug.Conn.html#module-fetchable-fields

1 Like
  1. Do “params” always contain only the query string/params - from the URL?

  2. Can “params” contain body params instead or in addition to Query String params?

But that’s for Plug!

Phoenix uses plug!

Try this

def my_post_handler(%Plug.Conn{body_params: body_params} = conn, _body_and_query_params) do
  # ...
end

Do “params” always contain only the query string/params - from the URL?

In phoenix controller “actions”, the second argument by default contains both body and query params.

1 Like

And how can I distinguish between query and body params?

conn.body_params or conn.query_params

11 Likes

And how can I distinguish between query and body params?

You can’t if you use the second argument in a phoenix controller action.

1 Like

For note, Phoenix is just ‘more’ on plug, it still uses the plug interfaces, plug calls, plug everything, it just adds things like a templating system and websockets an such. :slight_smile:

As an aside, I wish Phoenix URL arguments came in the param map via atom keys, where query arguments came in via string keys…

How do you propose to implement this safely without some major macro witchcraft? Namely something lime rewriting function heads so that pattern matches with maps become pattern matches with strings or something like that?

%{"string_key" => param_val, :atom_key => url_arg_val} should work just fine. No macro witchcraft.

1 Like

Yep, what @gregvaughn said, you can even do this syntax (just keep the atoms at the end because of elixir syntax parser annoyance):

%{"string_key" => param_val, atom_key: url_arg_val}

But when Phoenix creates the map for the function head to match, it will have to comvert some strings into atoms. Are you saying this is safe because the url params are static? If so, then I agree.

Yep, and it only has to do that at compile-time too. :slight_smile: