Previous    |   Up   |    Next

Don't collapse HTTPoison response headers

Today I learned…

The ergonomics of Keyword.t and proplist-like data structures in Elixir are less than ideal. In particular, keyword lists as function arguments preclude advanced pattern-matching in function heads.

Recently, I’ve grown fond of the following pattern: I write multi-parameter functions is such a way that callers can provide either a keyword-list or a map, but internally I always transform this parameter into a map.

This allows for much more precision in determining which arguments are required, and which can be filled in with some default value.

For example:

def picky_function(args) do
  %{a: required, b: required} = args = Enum.into(args, %{})
  c = Map.get(args, :c, "sane default")
  d = Map.get(args, :d, 12345)

This practice led me to underestimate situations where proplist-like datastructures are there for a reason. Case in point: %HTTPoison.Response.headers

I’d been accessing the response headers through my headers = Enum.into(headers, %{}) utility pattern, but it turns out this is absolutely the wrong thing to do for Set-Cookie headers. There may be more than one Set-Cookie coming back with the server response. I’d been handling only one cookie in my Elixir client program, because there could only exist one "Set-Cookie" key in the args map.

TIL: Always be ready to handle multiple Set-Cookie headers in an HTTPoison response struct, and never ever flatten them into a map.

This is also documented in the HTTPoison repo.

Previous    |   Up   |    Next