I came across this example of how nice and concise Elixir can be. It's a simple Github API client that does quite a bit in a small space. I like it.
Elixir can pack a lot into a little. I do have doubts if I'm over compacting it a bit but but frankly I like this. Here's a simple snippet of a Github API Client doing quite a bit of lifting in a small space.
1defmodule Github.API do 2 @moduledoc """ 3 Provides common functions to extract data from the Github API. 4 """ 5 @base_api_url "https://api.github.com/" 6 7 alias Github.UserRepository 8 alias Github.UserProfile 9 alias Github.UserEvents 10 alias Github.UserGists 11 12 @doc "Get the user profile" 13 def get_user_profile(username), 14 do: get("users/#{username}") |> handle_response(&UserProfile.new/1) 15 16 @doc "get the user profile, raise an exception if not ok" 17 def get_user_profile!(username), do: get_user_profile(username) |> unwrap_or_raise!() 18 19 @doc "get the users' repositories" 20 def repositories(username), 21 do: get("users/#{username}/repos") |> handle_response(&UserRepository.new/1) 22 23 @doc "get the users' repositories or raise an exception" 24 def repositories!(username), do: repositories(username) |> unwrap_or_raise!() 25 26 @doc "get the events for a user" 27 def events(username), 28 do: get("users/#{username}/events") |> handle_response(&UserEvents.new/1) 29 30 @doc "get the events for a user, raise an exception on error" 31 def events!(username), do: events(username) |> unwrap_or_raise!() 32 33 @doc "get the gists for a user" 34 def gists(username), 35 do: get("users/#{username}/gists") |> handle_response(&UserGists.new/1) 36 37 @doc "get the gists for a user, raise an exception on error" 38 def gists!(username), do: gists(username) |> unwrap_or_raise!() 39 40 # Handle unwrap functions 41 defp unwrap_or_raise!({:ok, res}), do: res 42 defp unwrap_or_raise!({:error, reason}), 43 do: raise("Github API request failed: #{inspect(reason)}") 44 45 # Start basic client functions here, these focus on the actual request and body 46 defp get_service_token(), do: Application.fetch_env!(:service, :github_api_token) 47 48 defp headers(), do: [{"Authorization", "Bearer #{get_service_token()}"}] 49 50 defp request_url(path), do: "#{@base_api_url}#{path}" 51 52 defp get(path), do: HTTPoison.get(request_url(path), headers()) 53 54 defp handle_response({:ok, %HTTPoison.Response{status_code: 200, body: body}}, _transform) do 55 case Poison.decode(body) do 56 {:ok, parsed_body} when is_list(parsed_body) -> 57 {:ok, Enum.map(parsed_body, _transform)} 58 59 {:ok, parsed_body} -> 60 {:ok, transform(parsed_body)} 61 62 {:error, reason} -> 63 {:error, {:decode_failed, reason}} 64 end 65 end 66 67 defp handle_response({:ok, %HTTPoison.Response{status_code: code}}, _transform), do: {:error, {:unhandled_status_code, code}} 68end
Thanks to ChatGPT for converting the code in the source image to actual code.
If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts, subscribe use the RSS feed.