TL;DR
Is there a more performant and clean way to call methods when I only know which methods (and modules) I will call after a response from the database
This question uses phoenix but is not about phoenix
I have a endpoint (lets call it legacy_reports) that return report files metadata to the user,like name, size, and download link.
My original problem was that when this endpoint was made, it was made for a specif report generator and to refactor everything in the back and in the front would take about 3 or 5 days. So I tweaked a bit the controller and the view of legacy_reports and added the new report to it.
To not suffer from the same problem in the future, I implemented a behaviour to extract the data from the report, and added the following code to the view.
def render("index.json", %{legacy_reports: leagacy_reports, new_reports: new_reports}) do
%{
legacy_reports:
render_many(legacy_reports, LegacyReportView, "legacy_report.json", as: :legacy_report) ++
render_many(new_reports, LegacyReportView, "new_report.json", as: :new_report)
}
end
def render("show.json", %{legacy_report:legacy_report}) do
%{legacy_report: render_one(legacy_report, LegacyReportView, "Legact_report.json")}
end
def render("legacy_report.json", %{new_report: new_report}) do
module_atom =
case new_report.service do
"SomeService" -> :"Elixir.MyApp.Reports.SomeService"
_ -> nil
end
%{
some_key: apply(module_atom, :extract_some_key, [new_report]),
...
}
end
def render("legacy_report.json", %{legacy_report: legacy_report}) do
{start_date, end_date} = decode_report_info(legacy_report.report_info)
%{
some_key: legacy_report.some_key,
...
}
end
...
But since this a dynamic way to use apply, I’m afraid it will have some performance drawbacks. Is there a better way to do it without using a whole lot of cases?