Hello, I am currently doing a phoenix JSON API, and I’ve met an uncommon problem.
Note that I used phx.gen.json for most of the code.
Here is my scope /api
scope "/api", WorklistWeb do
pipe_through :api
#get "/modalities/aet=:aet", ModalityController, :show #Break the POST somehow ?????
# OK so after investigating. Using another atom than :show (ex :sow) and changing the function in controller works.
# Meaning, the POST Route helper must try to find a controller with the :show atom, and doesn't pattern match.
get "/examens/day=:day", ExamenController, :index
resources "/patients", PatientController, except: [:new, :edit]
resources "/modalities", ModalityController, except: [:new, :edit]
resources "/examens", ExamenController, except: [:new, :edit]
end
And the ModalityController parts which concern the problem
def create(conn, %{"modality" => modality_params}) do
with {:ok, %Modality{} = modality} <- Modalities.create_modality(modality_params) do
conn
|> put_status(:created)
|> put_resp_header("location", Routes.modality_path(conn, :show, modality))
|> render("show.json", modality: modality)
end
end
def show(conn, %{"id" => id}) do
modality = Modalities.get_modality!(id)
render(conn, "show.json", modality: modality)
end
def show(conn, %{"aet" => aet}) do
modality = Modalities.get_modality_by_aet!(aet)
render(conn, "show.json", modality: modality)
end
So as I wrote in my scope comment, somehow the first route which is a pattern for get with URL arg, redirecting to the show function in the controller, broke my POST. This pattern work fine for GET, both with and without args. But it seem that « Routes.modality_path » from create match on my first GET route and it causes some error.
I found out that unit another atom that show for my first route seem to solve everything, but it doesn’t feel the right way, considering I could pattern match my GET just fine.
The error appear to be
[error] #PID<0.947.0> running WorklistWeb.Endpoint (connection #PID<0.922.0>, stream id 2) terminated
Server: localhost:4000 (http)
Request: POST /api/modalities
** (exit) an exception was raised:
** (ArgumentError) errors were found at the given arguments:
* 1st argument: not a bitstring
This typically happens when calling Kernel.byte_size/1 with an invalid argument or when performing binary construction or binary concatenation with <> and one of the arguments is not a binary
:erlang.byte_size(%Worklist.Modalities.Modality{__meta__: #Ecto.Schema.Metadata<:loaded, "modalities">, aet: "DICOMSTUFF1", id: 13, inserted_at: ~N[2022-03-08 16:48:33], modality: "DC", updated_at: ~N[2022-03-08 16:48:33]})
(worklist 0.1.0) WorklistWeb.Router.Helpers.modality_path/4
(worklist 0.1.0) lib/worklist_web/controllers/modality_controller.ex:18: WorklistWeb.ModalityController.create/2
(worklist 0.1.0) lib/worklist_web/controllers/modality_controller.ex:1: WorklistWeb.ModalityController.action/2
(worklist 0.1.0) lib/worklist_web/controllers/modality_controller.ex:1: WorklistWeb.ModalityController.phoenix_controller_pipeline/2
(phoenix 1.6.6) lib/phoenix/router.ex:355: Phoenix.Router.__call__/2
(worklist 0.1.0) lib/worklist_web/endpoint.ex:1: WorklistWeb.Endpoint.plug_builder_call/2
(worklist 0.1.0) lib/plug/debugger.ex:136: WorklistWeb.Endpoint."call (overridable 3)"/2
(worklist 0.1.0) lib/worklist_web/endpoint.ex:1: WorklistWeb.Endpoint.call/2
(phoenix 1.6.6) lib/phoenix/endpoint/cowboy2_handler.ex:54: Phoenix.Endpoint.Cowboy2Handler.init/4
(cowboy 2.9.0) /Users/clementauger/Desktop/Elixir/worklist/deps/cowboy/src/cowboy_handler.erl:37: :cowboy_handler.execute/2
(cowboy 2.9.0) /Users/clementauger/Desktop/Elixir/worklist/deps/cowboy/src/cowboy_stream_h.erl:306: :cowboy_stream_h.execute/3
(cowboy 2.9.0) /Users/clementauger/Desktop/Elixir/worklist/deps/cowboy/src/cowboy_stream_h.erl:295: :cowboy_stream_h.request_process/3
(stdlib 3.17) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
Any ideas ?