Reputation: 3
I am learning how to use Phoenix to create RESTful API. My steps as follows:
step1: use mix task create database schema and some code
mix phx.gen.context AnimalAdmin Animal animal name:string email:string:unique role:string address:string
mix phx.gen.json AnimalAdmin Animal animal name:string email:string:unique role:string address:string --no-context --no-schema
step2: update my repository by running
mix ecto.migrate
step3: update router.ex file
pipe_through :api
get "/animal", AnimalController, :index
put "/animal", AnimalController, :edit
post "/animal", AnimalController, :create
delete "/animal", AnimalController, :delete
step4: start server
mix phx.server
The animal_controller.ex file is
defmodule InvestmentBackWeb.AnimalController do
use InvestmentBackWeb, :controller
alias InvestmentBack.AnimalAdmin
alias InvestmentBack.AnimalAdmin.Animal
action_fallback InvestmentBackWeb.FallbackController
def index(conn, _params) do
animal = AnimalAdmin.list_animal()
render(conn, "index.json", animal: animal)
end
def create(conn, %{"animal" => animal_params}) do
with {:ok, %Animal{} = animal} <- AnimalAdmin.create_animal(animal_params) do
conn
|> put_status(:created)
# |> put_resp_header("location", Routes.animal_path(conn, :show, animal))
|> render("show.json", animal: animal)
end
end
def show(conn, %{"id" => id}) do
animal = AnimalAdmin.get_animal!(id)
render(conn, "show.json", animal: animal)
end
def update(conn, %{"id" => id, "animal" => animal_params}) do
animal = AnimalAdmin.get_animal!(id)
with {:ok, %Animal{} = animal} <- AnimalAdmin.update_animal(animal, animal_params) do
render(conn, "show.json", animal: animal)
end
end
def delete(conn, %{"id" => id}) do
animal = AnimalAdmin.get_animal!(id)
with {:ok, %Animal{}} <- AnimalAdmin.delete_animal(animal) do
send_resp(conn, :no_content, "")
end
end
end
I want add a row data to my repository by phoenix RESTful API, and use postman as this
When send a HTTP request, the response' code is 400, and error message is :
no function clause matching in InvestmentBackWeb.AnimalController.create/2
The following arguments were given to InvestmentBackWeb.AnimalController.create/2:
# 1
%Plug.Conn{adapter: {Plug.Cowboy.Conn, :...}, assigns: %{}, body_params: %{"address" => "china", "email" => "[email protected]", "name" => "xingxingliu", "role" => "new developer"}, cookies: %{}, halted: false, host: "localhost", method: "POST", owner: #PID<0.555.0>, params: %{"address" => "china", "email" => "[email protected]", "name" => "xingxingliu", "role" => "new developer"}, path_info: ["animal"], path_params: %{}, port: 4000, private: %{InvestmentBackWeb.Router => {[], %{Plug.Swoosh.MailboxPreview => ["mailbox"]}}, :before_send => [#Function<0.11807388/1 in Plug.Telemetry.call/2>, #Function<1.86886788/1 in Phoenix.LiveReloader.before_send_inject_reloader/3>], :phoenix_action => :create, :phoenix_controller => InvestmentBackWeb.AnimalController, :phoenix_endpoint => InvestmentBackWeb.Endpoint, :phoenix_format => "json", :phoenix_layout => {InvestmentBackWeb.LayoutView, :app}, :phoenix_request_logger => {"request_logger", "request_logger"}, :phoenix_router => InvestmentBackWeb.Router, :phoenix_view => InvestmentBackWeb.AnimalView, :plug_session_fetch => #Function<1.84243074/1 in Plug.Session.fetch_session/1>}, query_params: %{}, query_string: "", remote_ip: {127, 0, 0, 1}, req_cookies: %{}, req_headers: [{"accept", "*/*"}, {"accept-encoding", "gzip, deflate, br"}, {"connection", "keep-alive"}, {"content-length", "118"}, {"content-type", "application/json"}, {"host", "localhost:4000"}, {"postman-token", "5528ed3e-d8de-4e2e-82e3-2d7b1b3bde39"}, {"user-agent", "PostmanRuntime/7.31.3"}], request_path: "/animal", resp_body: nil, resp_cookies: %{}, resp_headers: [{"cache-control", "max-age=0, private, must-revalidate"}, {"x-request-id", "F0-VSsiF-LxMK_gAAAAC"}], scheme: :http, script_name: [], secret_key_base: :..., state: :unset, status: nil}
# 2
%{"address" => "china", "email" => "[email protected]", "name" => "xingxingliu", "role" => "new developer"}
I don't why problem appear. I will be greatly appreciated someone points out.
the elixir version:
Erlang/OTP 25 [erts-13.1.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit] [dtrace]
Elixir 1.14.2 (compiled with Erlang/OTP 25)
the phoenix version is 1.6.16
Upvotes: 0
Views: 192
Reputation: 222198
The generated Phoenix Controller expects the Animal data to be inside the key "animal"
, not at the top level. You can fix this by modifying your Postman request to have the body like this:
{
"animal": {
"name": "something",
"email": "...",
...
}
}
Upvotes: 1