Elixir
httpoison

HTTPoisonでクエリストリング

get!の第3引数で、:paramsにキーワードリストをわたせばよい。
ドキュメントにもちゃんとかいてある。requestのOptionsのところにかいてある。

:params - an enumerable consisting of two-item tuples that will be appended to the url as query string parameters

https://hexdocs.pm/httpoison/HTTPoison.html#request/5

Qiitaの誰かの記事で自分で作ってる例があったので、記録したが、元の記事が見つからない(汗

sample.exsを作成

sample.exs
url = "http://httpbin.org/get"
%HTTPoison.Response{body: body} = HTTPoison.get!(url, [], params: [hoge: 1])
IO.puts(body)

実行確認

$ mix run sample.exs | jq .
{
  "args": {
    "hoge": "1"
  },
  "headers": {
    "Connection": "close",
    "Host": "httpbin.org",
    "User-Agent": "hackney/1.10.1"
  },
  "origin": "180.220.192.160",
  "url": "http://httpbin.org/get?hoge=1"
}
$ mix run sample.exs | jq .url
"http://httpbin.org/get?hoge=1"

雑談

Mapでも動く。当たり前だけど、キーワードリストのでないと複数の値が投げられないので注意。

Mapでgetしてみる。

sample3.exs
url = "http://httpbin.org/get"
params = %{hoge: 1, hoge: 2}
%HTTPoison.Response{body: body} = HTTPoison.get!(url, [], params: params)
IO.puts(body)

実行結果

$ mix run sample.exs | jq .url
"http://httpbin.org/get?hoge=2"

同じキー名で複数の値を送信する

sample3.exs
$ mix run sample.exs | jq .url
url = "http://httpbin.org/get"
params = [hoge: 1, hoge: 2]
%HTTPoison.Response{body: body} = HTTPoison.get!(url, [], params: params)
IO.puts(body)
$ mix run sample.exs | jq .url
"http://httpbin.org/get?hoge=1&hoge=2"

ちなみに、 [hoge: [1,2]]のようにリストを渡しても動かない。
不思議な挙動ではないが、ユーザーフレンドリーではない。

url = "http://httpbin.org/get"
params = [hoge: [1,2]]
%HTTPoison.Response{body: body} = HTTPoison.get!(url, [], params: params)
IO.puts(body)
$ mix run sample.exs
** (ArgumentError) encode_query/1 values cannot be lists, got: [1, 2]
    (elixir) lib/uri.ex:100: URI.encode_kv_pair/1
    (elixir) lib/enum.ex:1343: anonymous fn/4 in Enum.map_join/3
    (elixir) lib/enum.ex:1829: Enum."-map_join/3-lists^foldl/2-0-"/3
    (elixir) lib/enum.ex:1829: Enum.map_join/3
    (httpoison) lib/httpoison.ex:66: HTTPoison.request/5
    (httpoison) lib/httpoison.ex:66: HTTPoison.request!/5
    get_query_string.exs:3: (file)

mix.exs

mix.exs
defmodule HttpoisonSample.Mixfile do
  use Mix.Project

  def project do
    [
      app: :httpoison_sample,
      version: "0.1.0",
      elixir: "~> 1.5",
      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
    [
      {:httpoison, "~> 0.13"}
      # {:dep_from_hexpm, "~> 0.3.0"},
      # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"},
    ]
  end
end