Hello,
I’m struggling to figure out why my api is sending me a 400 error on create route. Show and index route are working fine.
I tried different playload, I double check there was no error in json playload and
Here is my controller (auto generated with phoenix generator):
defmodule ColdDataApiWeb.ProjectController do
use ColdDataApiWeb, :controller
alias ColdDataApi.Record
alias ColdDataApi.Record.Project
action_fallback ColdDataApiWeb.FallbackController
def index(conn, _params) do
projects = Record.list_projects()
render(conn, "index.json", projects: projects)
end
def create(conn, %{"project" => project_params}) do
with {:ok, %Project{} = project} <- Record.create_project(project_params) do
conn
|> put_status(:created)
|> put_resp_header("location", project_path(conn, :show, project))
|> render("show.json", project: project)
end
end
def show(conn, %{"id" => id}) do
project = Record.get_project!(id)
render(conn, "show.json", project: project)
end
def update(conn, %{"id" => id, "project" => project_params}) do
project = Record.get_project!(id)
with {:ok, %Project{} = project} <- Record.update_project(project, project_params) do
render(conn, "show.json", project: project)
end
end
def delete(conn, %{"id" => id}) do
project = Record.get_project!(id)
with {:ok, %Project{}} <- Record.delete_project(project) do
send_resp(conn, :no_content, "")
end
end
end
My schema:
defmodule ColdDataApi.Record.Project do
use Ecto.Schema
import Ecto.Changeset
schema "projects" do
field :name, :string
field :short_description, :string
field :description, :string
field :human_name, :string
end
@allowed_fields [:name, :short_description, :description, :human_name]
@required_fields [:name, :short_description, :human_name]
@doc false
def changeset(project, attrs) do
project
|> cast(attrs, @allowed_fields)
|> validate_required(@required_fields)
|> validate_length(:name, max: 40, count: :codepoints)
|> validate_length(:short_description, max: 600, count: :codepoints)
|> validate_length(:human_name, max: 40, count: :codepoints)
|> validate_length(:description, max: 65_535, count: :codepoints)
|> unique_constraint(:name)
end
end
My FallbackController:
defmodule ColdDataApiWeb.FallbackController do
@moduledoc """
Translates controller action results into valid `Plug.Conn` responses.
See `Phoenix.Controller.action_fallback/1` for more details.
"""
use ColdDataApiWeb, :controller
def call(conn, {:error, %Ecto.Changeset{} = changeset}) do
conn
|> put_status(:unprocessable_entity)
|> render(ColdDataApiWeb.ChangesetView, "error.json", changeset: changeset)
end
def call(conn, {:error, :not_found}) do
conn
|> put_status(:not_found)
|> render(ColdDataApiWeb.ErrorView, :"404")
end
end
I add the routes like this:
# Other scopes may use custom stacks.
scope "/api/v1", ColdDataApiWeb do
pipe_through :api
resources "/projects", ProjectController, except: [:new, :edit]
end
I tested in iex console, Record.create_project works. I suppose the error come from the controller.
Does anyone could give me an hint on this error ?
Ps: english is not my mother tongue, so do not hesitate to ask me question if something is unclear.