ElixirのHTTPクライアントでお天気情報を取得したい(2022年)

[Elixir]のHTTPクライアントについて検索してみるといろいろ出てきます。中には廃盤になったものもいくつかあります。先日[Alex Koutmos]さんの[The State of Elixir HTTP Clients]という記事を読んで、2022年現在で使えるHTTPクライアントがわかったので、それらを使用して簡単なGETリクエストで[お天気情報]を取得してみようと思います。

[お天気情報]: https://wttr.in/
[Alex Koutmos]: https://twitter.com/akoutmos
[The State of Elixir HTTP Clients]: https://blog.appsignal.com/2020/07/28/the-state-of-elixir-http-clients.html

## TL;DR

迷ったら[req]を使うのが無難。

```elixir
%Req.Response{status: 200, body: body} = Req.get!("https://wttr.in/?format=j1")
```

https://qiita.com/torifukukaiou/items/4d842c6acae2b8967467

https://qiita.com/torifukukaiou/items/130a6ba0b16e1fddf24f


## 準備

[IEx]を開く。

```elixir
iex
```

[IEx]内でいくつかHexパッケージをインストール。

```elixir
Mix.install [:req, :httpoison, :tesla, :jason]
```

## [Elixir]で使えるHTTPクライアント

### [httpc]

- [Erlang]モジュールなので何もインストールしなくても使える。
- シンプルなHTTPリクエストにはこれで十分。
- HTTPレスポンスボディは[Charlist]。

[httpc]: https://www.erlang.org/doc/man/httpc.html

```elixir
{:ok, {{_, 200, _}, _headers, body}} = :httpc.request("https://wttr.in/?format=j1")
body |> List.to_string() |> Jason.decode!()
```

### [httpoison]

- [Erlang]で書かれた[hackney]というライブラリを使いやすくラップしたもの。
- [hackney]はトラフィック量の多いシナリオに対応できていないらしい。
- HTTPレスポンスボディは[String]。

[hackney]: https://github.com/benoitc/hackney
[httpoison]: https://hexdocs.pm/httpoison/HTTPoison.html

```elixir
%HTTPoison.Response{status_code: 200, body: body} = HTTPoison.get!("https://wttr.in/?format=j1")
body |> Jason.decode!()
```

### [tesla]

- Rubyの[faraday]にインスパイアされたらしい。
- [plug]に似た形でミドルウエアを追加できる。
- HTTPクライアントをモジュールとして構成したい場合に便利。
- テストのモックを用意できる。
- HTTPレスポンスボディは解析済みの[Map]。

[tesla]: https://hex.pm/packages/tesla
[faraday]: https://lostisland.github.io/faraday/
[plug]: https://hex.pm/packages/plug

```elixir
defmodule Weather do
  use Tesla

  plug Tesla.Middleware.BaseUrl, "https://wttr.in"
  plug Tesla.Middleware.JSON

  def get!() do
    get!("/?format=j1")
  end
end

%Tesla.Env{status: 200, body: body} = Weather.get!()
body
```

### [mint]

- TCP/SSLソケットを操作するための低レベルでプロセスを使用しないツール。
- 単純な[receive/1]ブロックでデータを取り込む。

[mint]: https://hex.pm/packages/mint

### [finch]

- [mint]を使いやすくラップしたもの。
- 軽量で高性能。

[finch]: https://hex.pm/packages/finch
[telemetry]: https://github.com/beam-telemetry/telemetry

### [req]

- [mint]を使いやすくラップした[finch]をさらにラップした便利な高性能ツール。
- HTTPレスポンスボディは解析済みの[Map]。

[req]: https://hex.pm/packages/req

書き方A

```elixir
%Req.Response{status: 200, body: body} = Req.get!("https://wttr.in/?format=j1")
body
```

書き方B

```elixir
%Req.Response{status: 200, body: body} = (
  Req.build(:get, "https://wttr.in/?format=j1")
  |> Req.put_default_steps()
  |> Req.run!()
)

body
```

[IEx]: https://hexdocs.pm/iex/main/IEx.html
[Elixir]: https://elixir-lang.org/
[Erlang]: https://www.erlang.org/
[String]: https://hexdocs.pm/elixir/String.html
[Map]: https://hexdocs.pm/elixir/Map.html
[Charlist]: https://hexdocs.pm/elixir/List.html#module-charlists
[receive/1]: https://hexdocs.pm/elixir/Kernel.SpecialForms.html#receive/1

# <u><b>Elixirコミュニティに初めて接する方は下記がオススメです</b></u>
**Elixirコミュニティ の歩き方 －国内オンライン編－**<br>
https://speakerdeck.com/elijo/elixirkomiyunitei-falsebu-kifang-guo-nei-onrainbian
[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155423/f891b7ad-d2c4-3303-915b-f831069e28a4.png)](https://speakerdeck.com/elijo/elixirkomiyunitei-falsebu-kifang-guo-nei-onrainbian)
**日本には28箇所のElixirコミュニティがあります**<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155423/7fdc5db7-dfad-9d10-28f8-1e0b8830a587.png)
## 日程からイベントを探すならElixirイベントカレンダー:calendar:
** Elixirイベントカレンダー **<br>
[https://elixir-jp-calendar.fly.dev/](https://elixir-jp-calendar.fly.dev/)
[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109744/985acaa4-50c9-da42-ae32-50fbf9119e61.png)](https://elixir-jp-calendar.fly.dev/)