Our app makes multiple API calls with Mojito in a LiveView. Sometimes the requests timeout (or maybe some other error) and it crashes the view.
What are some strategies I can use to handle it? The api calls sometimes depend on the results of previous calls.
One thing that comes to mind is:
with {:ok, result_1} <- api_call_1,
{:ok, result_2} <- api_call_2(result_1[:id]) do
{:ok, assign(socket, result_1: result_1, result_2: result_2)}
else
{:ok, assign(socket, result_1: nil, result_2: nil)}
end
Then in the template I can somehow handle nil values.
What else is possible? Ideally for a timeout, I want to just retry. Maybe I need to just increase the timeout? Or make the calls with Task.async or a GenServer?
Hi, I don’t know Mojito but let me show you Mint. It creates all requests async and response will come as a message. You can find more information about their architecture and GenServer implementation here
The idea is when you have LiveView you can call GenServer with current implementation for that call and doesn’t care more about it. Or even you can implement that Mint’s architecture in LiveView module. You have to just implement handle_info functions and call api responses. When you get timetout you can do retry or whatever. With this approach your LiveView has to be stable, because all risky work is made outside the process. Dependency with api_call_1 -> api_call_2 is also possible. You call api_call_2 in handle_info function which handle (pattern match) successful response from api_call_1.
Don’t forget when you do some long work inside handle_* functions your LiveView will freeze until you finish it.
I haven’t done any HTTP in my Elixir projects but last time I tried to use Erlang’s Gun and was very impressed. Loved the granularity and control and I highly recommend it.