Created
March 21, 2019 15:28
-
-
Save bmartin2015/41c6e45a158e4649f309873161508908 to your computer and use it in GitHub Desktop.
Consume a paginated API in Elixir via Stream.resource/3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule ResultStream do | |
# Start the stream | |
def new(url) do | |
Stream.resource( | |
fn -> fetch_page(url) end, | |
&process_page/1, | |
fn _ -> nil end | |
) | |
end | |
def fetch_page(url) do | |
response = get(url) # I use Tesla, but whatever HTTP client you are using | |
items = response.body["data"] # for Drift API | |
next_page_url = parse_links(response) # Best way to do this will depend on the API | |
{items, next_page_url} | |
end | |
defp parse_links(_, nil), do: nil | |
defp parse_links(url, link) do | |
%{url: url, next: link["next"]} | |
end | |
defp process_page({nil, nil}), do: {:halt, nil} | |
defp process_page({nil, next_page_url}) do | |
next_page_url | |
|> fetch_page() | |
|> process_page() | |
end | |
defp process_page({items, next_page_url}) do | |
{items, {nil, next_page_url}} | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment