Customize AshJsonApi route to return raw binary

I have an API route with AshJsonApi that generates an image that needs to be sent back to the user.

I wanted to know if there is some way to customize an route so I can change the return type from “application/json” to “image/png” and send the binary directly in the body.

I know I can achieve something similar by creating a base64 of the image binary or storing it somewhere and return an url, but I would prefer to send the raw binary back if possible.

Here is my action:

action :render, :binary do
  run fn _, _ ->
    some_binary = <<>>
    {:ok, some_binary}
  end
end

Update:

So, I added this to my route to change the conn:

        route :post, "render", :render do
          modify_conn fn conn, subject, result, request ->
            conn
            |> Plug.Conn.put_resp_content_type("image/png")
            |> Plug.Conn.send_resp(200, <<213>>)
          end
        end

This will “work”, it sends the response the way I want.. But, right after the modify_conn, ash json api will call its own controller (ash_json_api/controllers/response.ex) and try to send the json value too, giving the [error] ** (Plug.Conn.AlreadySentError) the response was already sent error since I already sent the response before.

So I guess there is no scapegoat right now to achieve that?

1 Like

We could likely support changing the response type for routes and then you’d just return the binary. Like if you change the return type you’d be responsible for ensuring whatever it is can be put into a response.