Elixir App

Elixir App

Idea

Hi, I’ll be working on elixir app for multi upload. Main idea is to contact multiple API’s and send some data. Everything will be done via DynamicSupervisor and multiple workers so it could enable concurrency.

Tools

I will use swagger to generate the elixir client as it is fairly easy to generate the api with it. Below is command I used to generate api client for YouTube.

java -jar swagger-codegen-cli-2.4.8.jar generate -l elixir -i api_spec\youtube.yaml -o lib\elixir-clients\youtube

As for deps I used they are listed below.

defp deps do
    [
      {:tesla, "~> 0.8"},
      {:poison, "~> 1.3.1"}
    ]
end

Tesla will be used for making the connection to API and Poison is used for JSON encoding/decoding. Elixir SDK used is at version 1.9.1.

Errors

I had error with poison encoding, as it had to get the map for encoding decoding from API models. To resolve this problem I had to add function Map.from_struct/2.. If you are working with swagger-codegen this will make you some problems with API integration.

 defmodule YouTubeData.Deserializer do
  @spec deserialize(struct(), :atom, :atom, struct(), keyword()) :: struct()
  def deserialize(model, field, :list, mod, options) do
    # adding Map.from_struct(mod) will resolve any decoding errors
    model
    |> Map.update!(field, &(Poison.Decode.decode(&1, [as: [Map.from_struct(mod)]])))
  end
  def deserialize(model, field, :struct, mod, options) do
    model
    |> Map.update!(field, &(Poison.Decode.decode(&1, [as: Map.from_struct(mod)])))
  end
  def deserialize(model, field, :map, mod, options) do
    model
    |> Map.update!(field, &(Map.new(&1, fn {key, val} -> {key, Poison.Decode.decode(val, Keyword.merge(options, [as: Map.from_struct(mod)]))} end)))
  end
  def deserialize(model, field, :date, _, _options) do
    value = Map.get(model, field)
    case is_binary(value) do
      true -> case DateTime.from_iso8601(value) do
                {:ok, datetime, _offset} ->
                  Map.put(model, field, datetime)
                _ ->
                  model
              end
      false -> model
    end
  end
end