How to define a route like /properties/filter_objects alongside /properties/:id

I want to have two GET routes working like this:

a. /properties/:id
b. /properties/filter_objects

a. handled by the normal show action and b. by a custom controller action. I have achieved this by doing:

  def show(conn, %{"id" => id}, user) when id != "filter_objects" do
    property = Properties.get_property!(id)
    render(conn, "show.json", property: property)
  end

  def show(conn, %{"id" => id}, user) when id == "filter_objects" do
    users = User |> Repo.all
    pretty_json(conn, %{users: users})
  end

Is there a better way to achieve this? Thank you.

def show(conn, %{"id" => "filter_objects"}, user) do
    users = User |> Repo.all
    pretty_json(conn, %{users: users})
  end

  def show(conn, %{"id" => id}, user) do
    property = Properties.get_property!(id)
    render(conn, "show.json", property: property)
  end
1 Like

@LostKobrakai

Thank you. This seems fine. I thought the Phoenix way to do this is by some definitions in router.ex. Your suggestion makes things simpler.

One question, is the order of function definitions important?

The phoenix way to do this β€˜is’ in the Router. ^.^

Put the specific route /properties/filter_objects first then the generic route /properties/:id second so it gets matched on in order, can even have them go to different functions. :slight_smile:

1 Like

I have managed to achieve that by:

  scope "/api", RentalWeb.Api do
    pipe_through :api
    
    get "/properties/filter_objects", PropertyController, :filter_objects
    resources "/properties", PropertyController
  end``
1 Like