I have a route where I need to receive an uploaded image and a json payload, to do that, I’m using multipart/form-data.
The issue is that when I receive the payload in my controller, the json part is not decoded properly, I receive it in string form.
Here is my curl request, as you can see, I am passing the corret content-type for the json payload:
curl -X POST http://localhost:4000/api/qr_code/simple \
-H "Content-Type:multipart/form-data" \
-F "file=@logo.svg;type=image/svg+xml" \
-F "payload={\"my\":\"json\"};type=application/json"
The only way I managed to achieve that was to create a plug myself that do the decode:
defmodule MyParser do
@moduledoc false
@behaviour Plug
def init(opts) do
key = opts |> Keyword.fetch!(:key) |> to_string()
key
end
def call(%{req_headers: req_headers} = conn, key) do
with {"content-type", content_type} <- List.keyfind(req_headers, "content-type", 0),
true <- String.starts_with?(content_type, "multipart/form-data") do
maybe_parse_key_content(conn, key)
else
_ -> conn
end
end
defp maybe_parse_key_content(%{body_params: body_params} = conn, key) do
with {:ok, content} when is_binary(content) <- Map.fetch(body_params, key),
{:ok, decoded_content} <- Jason.decode(content) do
put_in(conn, [Access.key(:body_params), key], decoded_content)
else
_ -> conn
end
end
end
It works, but I feel that Phoenix should do that automatically.
So, is there some way to tell the Phoenix Controller to properly parse that field for me?






















