Add the dependency to your project and install it.
So, back to our problem. We have to write the function GithubIssues.fetch, which transforms a user name and project into a data structure containing that project’s issues. The HTTPoison page on GitHub gives us a clue,[22] and we write a new module, Issues.GithubIssues:
| defmodule Issues.GithubIssues do |
| @user_agent [ {"User-agent", "Elixir dave@pragprog.com"} ] |
| |
| def fetch(user, project) do |
| issues_url(user, project) |
| |> HTTPoison.get(@user_agent) |
| |> handle_response |
| end |
| |
| def issues_url(user, project) do |
| "https://api.github.com/repos/#{user}/#{project}/issues" |
| end |
| |
| def handle_response({ :ok, %{status_code: 200, body: body}}) do |
| { :ok, body } |
| end |
| |
| def handle_response({ _, %{status_code: _, body: body}}) do |
| { :error, body } |
| end |
| end |
We simply call get on the GitHub URL. (We also have to pass in a user-agent header to keep the GitHub API happy.) What comes back is a structure. If we have a successful response, we return a tuple whose first element is :ok, along with the body. Otherwise we return an :error tuple, also with the body.
There’s one more thing. The examples on the HTTPoison GitHub page call HTTPoison.start. That’s because HTTPoison actually runs as a separate application, outside your main process. A lot of developers will copy this code, calling start inline like this.
In older versions of Elixir, you could add HTTPoison to the list of applications to start in mix.exs:
| def application do |
| [ applications: [ :logger, :httpoison ] ] |
| end |
This is no longer necessary. The fact that you have listed HTTPoison as a dependency means that mix will automatically start it as an application.
We can play with this in IEx. Use the -S mix option to run mix before dropping into interaction mode. Because this is the first time we’ve tried to run our code since installing the dependencies, you’ll see them get compiled:
| $ iex -S mix |
| Erlang/OTP 20 [erts-9.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-thr |
| eads:10] [hipe] [kernel-poll:false] |
| |
| ===> Compiling mimerl |
| ===> Compiling metrics |
| : : |
| Generated issues app |
| |
| iex(1)> |
Let’s try it out. (The output is massaged to fit the page.)
| iex> Issues.GithubIssues.fetch("elixir-lang", "elixir") |
| {:ok, |
| [ |
| {"url":"https://api.github.com/repos/elixir-lang/elixir/issues/7121", |
| "repository_url":"https://api.github.com/repos/elixir-lang/elixir", |
| "labels_url": |
| "https://api.github.com/repos/elixir-lang/elixir/issues/7121/labels{/name}", |
| "events_url":"https://api.github.com/repos/elixir-lang/elixir/issues/7121/events", |
| "html_url":"https://github.com/elixir-lang/elixir/issues/7121", |
| "id":282654795, |
| "number":7121, |
| "title":"IEx.Helpers.h duplicate output for default arguments", |
| "user":{ |
| "login":"wojtekmach", |
| "id":76071, |
| "avatar_url":"https://avatars0.githubusercontent.com/u/76071?v=4", |
| "gravatar_id":"", |
| "url":"https://api.github.com/users/wojtekmach", |
| "html_url":"https://github.com/wojtekmach", |
| "followers_url":"https://api.github.com/users/wojtekmach/followers", |
| . . . . . . . |
This tuple is the body of the GitHub response. The first element is set to :ok. The second element is a string containing the data encoded in JSON format.