As you may already know, the second version of our domain management API reached the General Availability milestone recently. One of the goals that we set for ourselves was supporting several languages by providing clients from the very beginning. Elixir is one of those languages.

You can check the DNSimple Elixir API client on GitHub. It's fully featured and maintained by several members of the DNSimple team. In fact, we are using the client extensively in several internal projects. This is the library that we will be using in this tutorial.

Getting ready

Let's get started. There are some initial steps that we have to go through before we can start making calls to the DNSimple API.

Subscribing

In order to follow this tutorial you will need an active subscription with DNSimple. You can see the offered plans and the included features for each of them on our pricing page. The subscription fee covers our various domain management automation services, which include API access.

The good news is that you can follow this tutorial without spending a dime: we have a sandbox environment ready for you. You can simply go to sandbox.dnsimple.com and subscribe to any of our plans there using the credit card number 1. You will be ready to use our API as much as you want.

Installing the client

With our account ready we can start with the fun part: writing code!

In this tutorial we are going to assume that you have Elixir installed on your machine. If you don't, you can follow the official documentation to get yourself ready.

The first step is to create a new Elixir app:

⌘ ~/dev ❯ mix new domaining
* creating README.md
* creating .gitignore
* creating mix.exs
* creating config
* creating config/config.exs
* creating lib
* creating lib/domaining.ex
* creating test
* creating test/test_helper.exs
* creating test/domaining_test.exs

Your Mix project was created successfully.

Now we have to edit our mix.exs file and add the DNSimple API client as a dependency. You will have to look for the deps function and update it so it looks like this:

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

Now you must install the newly added dependency:

⌘ ~/dev/domaining ❯ mix deps.get
Running dependency resolution
Dependency resolution completed
  certifi: 0.7.0
  dnsimple: 1.0.0
  hackney: 1.6.3
  httpoison: 0.10.0
  idna: 1.2.0
  metrics: 1.0.1
  mimerl: 1.0.2
  poison: 2.2.0
  ssl_verify_fun: 1.1.1
* Getting dnsimple (Hex package)
  Checking package (https://repo.hex.pm/tarballs/dnsimple-1.0.0.tar)
  Fetched package
...

Finally you will have to make sure to start the dnsimple OTP app when your application runs. Find the application function and add dnsimple to the list:

def application do
  [applications: [:logger, :dnsimple]]
end

Authenticating

With the Elixir application ready, we now need to learn how to make API calls. Looking at the library README we can see that we need to provide a Dnsimple.Client struct for each call:

{:ok, response} = Dnsimple.Identity.whoami(client)

This struct contains the required authentication data to perform the API call and the URL of the environment against which we are performing the API call (https://api.dnsimple.com being the default). You can provide a custom base_url so your client targets the sandbox environment:

client = %Dnsimple.Client{access_token: "TOKEN", base_url: "https://api.sandbox.dnsimple.com/"}

Obtaining an access token

The next question is: what is an access token and how do we obtain it?

The access token is a particular key that allows you to authenticate an API request. This is the preferred authentication mechanism over using your username and password, as you can easily delete and regenerate tokens without affecting your primary credentials.

The how to obtain an access token article provides step by step instructions for getting started.

With your token ready you can make your fist API call from IEx:

⌘ ~/dev/domaining ❯ iex -S mix
Erlang/OTP 19 [erts-8.2] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Interactive Elixir (1.3.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> client = %Dnsimple.Client{access_token: "TOKEN", base_url: "https://api.sandbox.dnsimple.com/"}
iex(2)> {:ok, response} = Dnsimple.Identity.whoami(client)

10:16:02.858 [debug] [dnsimple] GET https://api.sandbox.dnsimple.com/v2/whoami
{:ok,
 %Dnsimple.Response{data: %Dnsimple.Whoami{account: %Dnsimple.Account{email: "javier@dnsimple.com",
    id: 63, plan_identifier: "dnsimple-professional"}, user: nil},
  http_response: %HTTPoison.Response{body: "{\"data\":{\"user\":null,\"account\":{\"id\":63,\"email\":\"javier@dnsimple.com\",\"plan_identifier\":\"dnsimple-professional\",\"created_at\":\"2014-07-02T14:15:56Z\",\"updated_at\":\"2016-12-14T08:44:06Z\"}}}",
   headers: [{"Server", "nginx"}, {"Date", "Fri, 30 Dec 2016 09:16:03 GMT"},
    {"Content-Type", "application/json; charset=utf-8"},
    {"Transfer-Encoding", "chunked"}, {"Connection", "keep-alive"},
    {"X-RateLimit-Limit", "2400"}, {"X-RateLimit-Remaining", "2399"},
    {"X-RateLimit-Reset", "1483092963"},
    {"ETag", "W/\"d01b8b299498e2b3d9207dee0a2c92a1\""},
    {"Cache-Control", "max-age=0, private, must-revalidate"},
    {"X-Request-Id", "507de94f-f7ba-4b4f-b806-8d161fc3872b"},
    {"X-Runtime", "0.023295"}, {"X-Content-Type-Options", "nosniff"},
    {"X-Download-Options", "noopen"}, {"X-Frame-Options", "DENY"},
    {"X-Permitted-Cross-Domain-Policies", "none"},
    {"X-XSS-Protection", "1; mode=block"},
    {"Strict-Transport-Security", "max-age=31536000"}], status_code: 200},
  pagination: nil, rate_limit: 2400, rate_limit_remaining: 2399,
  rate_limit_reset: 1483092963}}
iex(3)> response.data
%Dnsimple.Whoami{account: %Dnsimple.Account{email: "javier@dnsimple.com",
  id: 63, plan_identifier: "dnsimple-professional"}, user: nil}

As you can see we have pattern matched the value returned by the call to Dnsimple.Identity.whoami to capture the response. Then we have extracted the data of the response by checking the data key of the returned struct. This is a pattern that you will repeat all the time when using the DNSimple Elixir API client.

Finding out your account id

There is one important bit of information in that response: your account_id. In my case my account_id on the sandbox environment is 63.

If you look through the different endpoints of the API you will see that you have to provide this value in most of them. There are several reasons for this which have been documented already and we are not going to repeat here.

If your app is always going to use the same account you can hard-code this value (or put it in a configuration setting). However, when your application deals with different users, you will have to provide a different account_id for each of them.

Wrapping up

That is all! Here is what you have achieved thus far:

  • You have a DNSimple account ready on the sandbox environment.
  • You have installed the dnsimple Elixir API client.
  • You have created a new mix app and configured dnsimple as a dependency.
  • You have generated an access_token that you can use to make API calls.
  • You have made your first call to the DNSimple API.

Now you are ready to grow the domaining app as much as you want.