I'm starting to use Phoenix outside of tutorials for a small use case. So far great, but I'm a bit taken aback by the following.
I have a resource "recording" that I want to access at /api/recordings in JSON and at /recording with a template and the result being HTML.
Ideally the Ecto representation would be unique, and even part of the controller would also be shared?
Right now I either have to have 2 resources recordingAPI and recordingHTML, or 2 controllers and 1 resources.
Any exemple out there? I keep finding one or the other, but not something with the :api pipe and the :browser pipe used for the same resource.
Thanks
You can utilize phoenix accepts plug and a combination of two different views/layouts
# router.ex
defmodule TestExWeb.Router do
  use TestExWeb, :router
  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_flash
    plug :protect_from_forgery
    plug :put_secure_browser_headers
  end
  pipeline :api do
    plug :accepts, ["json"]
  end
  scope "/", TestExWeb do
    pipe_through :browser
    get "/recording", PageController, :index
  end
  scope "/api", TestExWeb do
    pipe_through :api
    get "/recording", PageController, :index
  end
end
As you can see, :browser uses :accepts ["html"] while :api uses :accepts ["json"]. You can find this in the private struct of your conn and use it in the controller like this:
defmodule TestExWeb.PageController do
  use TestExWeb, :controller
  def index(%{private: %{phoenix_format: format}} = conn, _params) do
    data = "Hello World"
    render(conn, "index.#{format}", data: data)
  end
end
Now, you just need to tell phoenix how to render your json, html is already taken care of by page.html.eex in layouts, so add the following to your page_view.ex
defmodule TestExWeb.PageView do
  use TestExWeb, :view
  def render("index.json", %{data: data}) do
    %{
      data: data
    }
  end
end
Two drawbacks with this solution:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With