fukuoka.exのkoyoです
最近Goばっかり書いているのでそろそろElixirするかということで書いてみます!
お題
Github API を使って特定のリポジトリのcloseされたPR一覧を出してみる
プロジェクトの作成
mix new sample_ex
必要なライブラリの追加
今回はHTTPリクエストにHTTPoison, レスポンスボディのパースにPoisonを使います
defp deps do
[
{:httpoison, "~> 1.5"},
{:poison, "~> 4.0"}
# {:dep_from_hexpm, "~> 0.3.0"},
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
]
end
実装
対象リポジトリは昔作ったグラフ付きQiita検索アプリ
https://github.com/koyo-miyamura/vue_api_spa
defmodule SampleEx do
@moduledoc """
Documentation for SampleEx.
"""
@spec main :: :ok
def main() do
pr_list() |> Enum.each(fn x -> IO.puts(x) end)
end
@spec pr_list :: charlist()
def pr_list() do
build_url("https://api.github.com/repos/koyo-miyamura/vue_api_spa/pulls", %{
"state" => "closed"
})
|> HTTPoison.get!()
|> Map.get(:body)
|> Poison.decode!()
|> Enum.map(fn x -> format(x) end)
end
@doc """
build url.
## Examples
iex> SampleEx.build_url("http://example.com", %{"foo" => "bar"})
"http://example.com?foo=bar"
"""
@spec build_url(String.t(), map()) :: String.t()
def build_url(path, query) do
URI.parse(path)
|> Map.put(:query, URI.encode_query(query))
|> URI.to_string()
end
@doc """
format map
## Examples
iex> SampleEx.format(%{"title" => "title", "created_at" => "2018-10-06T23:46:53Z"})
"title 2018-10-06"
"""
@spec format(map()) :: String.t()
def format(map) do
map_title = Map.get(map, "title")
map_date =
Map.get(map, "created_at")
|> NaiveDateTime.from_iso8601!()
|> NaiveDateTime.to_date()
|> Date.to_string()
map_title <> " " <> map_date
end
end
Elixirで時刻扱うのはちょっとクセありますがこんな感じで
https://hexdocs.pm/elixir/NaiveDateTime.html#content
またURI文字列を作成する部分はURI
モジュールを使えば良いですが、クエリパラメータを結合する関数は用意されていなかったので以下を参考に自前で作ってみました
https://stackoverflow.com/questions/49508509/idiom-to-construct-a-uri-with-a-query-string-in-elixir
実行結果
キタ━(゚∀゚)━! $ iex -S mix
Erlang/OTP 21 [erts-10.3.4] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe] [dtrace]
Interactive Elixir (1.8.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> SampleEx.main
ユーザランキング 2018-10-06
vuexの導入 2018-10-06
チャート機能の実装 2018-10-06
Tag search 2018-10-05
Fix design 2018-10-04
Use vue cli 2018-09-30
vue-routerの導入 2018-09-29
Use component 2018-09-26
formから検索ワード変更する機能の追加 2018-09-25
見た目の調整 2018-09-24
できたぜ!!
テストについて
できる部分はdoctestしましたが、HTTPリクエストを行うpr_list
のテストはどうするのか分からず断念
Goだとnet/http
使ってモックするやり方が考えられますが、Elixirはモックを推奨していない様子
探してみると自前でサーバ立てるやり方が書いてました
んーちょっと大変?もっといいやり方募集中です
https://medium.com/flatiron-labs/rolling-your-own-mock-server-for-testing-in-elixir-2cdb5ccdd1a0
ちなみにHTMLをパースしたい場合
Flokiというライブラリがメジャーみたいです
mix.exs
に{:floki, "~> 0.21.0"}
すると使えます
感想
最近Goばっかり書いてたんですが「GoでやるアレElixirでどうするんだろう?」という題材で学習してみると学びが深まりました
iex使って動かしながら作れるので楽しい
皆さんも普段使っている言語でやっていることをElixirで実現してみると面白いですよ!