Where the API works with Phoenix, the API works with JSON.
But, when you test it and send JSON with curl , it fails because Phoenix does not parse the request as JSON. You need to explicitly add the application/json header in curl . I would like to make it more reliable and tell Phoenix to always parse all requests as JSON.
Is there a way to get Phoenix to always process requests as JSON and parse it as JSON?
UPDATE
I tried using a plug to set request headers, as @AbM suggested, with the following code in Router:
def set_format conn, format do Plug.Conn.put_private conn, :phoenix_format, format end def put_req_header conn, {key, value} do Plug.Conn.put_req_header conn, key, value end pipeline :api do plug :put_req_header, {"accept", "application/json"} plug :put_req_header, {"content-type", "application/json"} plug :set_format, "json" plug :accepts, ["json"] end
Request completed with CURL
curl -X POST http://localhost:4000/api/upload -d '{"key": "value"}'
The connection looks like this:
%Plug.Conn{adapter: {Plug.Adapters.Cowboy.Conn, :...}, assigns: %{}, before_send: [#Function<1.93474994/1 in Plug.Logger.call/2>, #Function<0.119481890/1 in Phoenix.LiveReloader.before_send_inject_reloader/1>], body_params: %{"{\"key\": \"value\"}" => nil}, cookies: %Plug.Conn.Unfetched{aspect: :cookies}, halted: false, host: "localhost", method: "POST", owner: #PID<0.483.0>, params: %{"{\"key\": \"value\"}" => nil}, path_info: ["api", "upload"], peer: {{127, 0, 0, 1}, 58408}, port: 4000, private: %{App.Router => {[], %{}}, :phoenix_action => :upload, :phoenix_controller => ApiController, :phoenix_endpoint => App.Endpoint, :phoenix_format => "json", :phoenix_layout => {LayoutView, :app}, :phoenix_pipelines => [:api], :phoenix_route => #Function<8.59735990/1 in App.Router.match_route/4>, :phoenix_router => App.Router, :phoenix_view => ApiView, :plug_session_fetch => #Function<1.89562996/1 in Plug.Session.fetch_session/1>}, query_params: %{}, query_string: "", remote_ip: {127, 0, 0, 1}, req_cookies: %Plug.Conn.Unfetched{aspect: :cookies}, req_headers: [{"user-agent", "curl/7.37.1"}, {"host", "localhost:4000"}, {"accept", "application/json"}, {"content-length", "16"}, {"content-type", "application/json"}], request_path: "/api/upload", resp_body: nil, resp_cookies: %{}, resp_headers: [{"cache-control", "max-age=0, private, must-revalidate"}, {"x-request-id", "xxx"}], scheme: :http, script_name: [], secret_key_base: "xxx", state: :unset, status: nil}
It works if I add the -H "Content-Type: application/json" parameter -H "Content-Type: application/json" to CURL, it does not work without it.