Send a downloadable file in API response using grahql in phoenix framework (absinthe)

783 Views Asked by At

I am currently sending json string in response to an API request in graphql using absinthe. The schema for it looks like this:

object :export_data do
    field :resp_data, :json
end

I want to now send a downloadable json file instead of a json string in the API response. My initial idea was to use a :file type in the absinthe schema and the return a file from resolver using File.write/2 or whatever data type is supported for files. But I couldn't find a file data type which is supported by absinthe in their documentation. How do I send a json file in a graphql API response?

1

There are 1 best solutions below

0
On

I think it's better to skip graphql here and do it over the controller. Here is a pseudo example of how to handle downloadable CSV files, also file type can be handled with put_resp_header.

CSV Controller

def download_csv(conn, %{"id" => id}) do
 
    fields = # Call fields from struct or DB

    header = Enum.map(fields, &Phoenix.Naming.humanize/1)

    items = # transform data more, Enum.map() |> etc...

    csv = CSV.encode([header] ++ items) |> Enum.join

    conn
    |> put_resp_content_type("text/csv")
    |> put_resp_header("content-disposition", ~s[attachment; filename="data.csv"])
    |> text(csv)
  end

Router

get "/csv/:id/download_csv", CsvController, :download_csv

Csv Template

<%= form_for @conn, Routes.customer_path(@conn, :download_csv, @customer.id), [method: :get], fn f -> %>
    <button class="btn btn-primary">Download Full CDRs</button>
 <% end %>