Step 2: Use Libraries

Learn how to add external libraries in Elixir.

Elixir comes with a bunch of libraries preinstalled. Some are written in Elixir, and others in Erlang.

The first port of call is the Elixir documentation. Often, we’ll find a built-in library that does what we want.

Next, we see if any standard Erlang libraries do what we need. This isn’t a simple task. We visit http://erlang.org/doc/ and look in the left sidebar for “Application Groups.” Here, libraries are sorted by top-level category.

If we find what we’re looking for in either of these places, we’re all set because all these libraries are already available to the application. But if the built-in libraries don’t contain what we need, we’ll have to add an external dependency.

Finding an external library

Ruby has RubyGems, Python has pip, Node.js has npm and Elixir has the Hex package manager.

Visit https://hex.pm and search the list of Elixir packages that integrate nicely with a Mix-based project.

If all else fails, Google and GitHub will work. We can search for terms such as “elixir http client” or “erlang distributed logger,” and the needed libraries are likely to turn up.

In our case, we need an HTTP client. We find that Elixir has nothing built in, but hex.pm has a number of HTTP client libraries.

HTTPoison looks like a good option. So, how do we include it in our project?

Adding a library to our project

Mix takes the view that all external libraries should be copied into the project’s directory structure. The good news is that it handles all this for us. We just need to list the dependencies, and it does the rest. Remember the mix.exs file at the top level of our project? Here’s that original version:

# The mix.exs file
defmodule Issues.MixProject do
  use Mix.Project

  def project do
    [
      app: :issues,
      version: "0.1.0",
      elixir: "~> 1.12",
      start_permanent: Mix.env() == :prod,
      deps: deps()
    ]
  end

  # Run "mix help compile.app" to learn about applications.
  def application do
    [
      extra_applications: [:logger]
    ]
  end

  # Run "mix help deps" to learn about dependencies.
  defp deps do
    [
      # {:dep_from_hexpm, "~> 0.3.0"},
      # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
    ]
  end
end

We add new dependencies to the deps function. As the HTTPoison package is in hex.pm, that’s very simple. We just give the name and the version we want.

defp deps do 
  [
   { :httpoison, "~> 1.0.0" } 
  ]
end

In this case, we give the version as "~> 1.0.0". This matches any version of HTTPoison with a major version of 1 and a minor version of 0 or greater. In IEx, we can type h Version for more details.

Once the mix.exs file is updated, we’re ready to have Mix manage our dependencies.

We use mix deps to list the dependencies and their statuses:

$ mix deps
* httpoison (package)
the dependency is not available, run `mix deps.get`

We download the dependencies with mix deps.get:

Resolving Hex dependencies...
Dependency resolution completed:
  certifi 2.0.0
  hackney 1.10.1
  httpoison 0.13.0
  idna 5.1.0
  metrics 1.0.1
  mimerl 1.0.2
  ssl_verify_fun 1.1.1
  unicode_util_compat 0.3.1
* Getting httpoison (Hex package)
Checking package (https://repo.hex.pm/tarballs/httpoison-0.13.0.tar) Using locally cached package
...

Then ,we run mix deps again:

* mimerl (Hex package) (rebar3)
  locked at 1.0.2 (mimerl) 993f9b0e
  the dependency build is outdated, please run "mix deps.compile"
* metrics (Hex package) (rebar3)
  locked at 1.0.1 (metrics) 25f094de
  the dependency build is outdated, please run "mix deps.compile"
* unicode_util_compat (Hex package) (rebar3)
locked at 0.3.1 (unicode_util_compat) a1f612a7
the dependency build is outdated, please run "mix deps.compile" ...
* httpoison (Hex package) (mix)
  locked at 0.9.0 (httpoison) 68187a2d
  the dependency build is outdated, please run "mix deps.compile"

This shows that the HTTPoison library is installed but that it hasn’t yet been compiled. Mix also remembers the exact version of each library it installs in the file mix.lock. This means that at any point in the future, we can get the same version of the library we use now. We don’t need to worry that the library isn’t compiled. Mix will automatically compile it the first time we need it.

If we look at our project tree, we find a new directory called deps containing our dependencies. Note that these dependencies are themselves just projects, so we can browse their source and read their documentation.

Back to the transformation

So, back to our problem. We have to write the function GithubIssues.fetch, which transforms a username and project into a data structure containing that project’s issues. The HTTPoison page on GitHub gives us a clue, and we write a new module, Issues.GithubIssues.

Get hands-on with 1400+ tech skills courses.