Оператор case при обработке вызова HTTPoison

Я пытаюсь использовать одни и те же вызовы HTTPoison для вызова API, который возвращает либо несколько элементов, либо один элемент. Ответ для нескольких элементов выбрасывает их в свойство "items", в то время как один элемент просто возвращает информацию об элементе в виде строки JSON.

Вот мой код:

  def process_url(method, id \\ 0) do
    if id > 0 do
      "http://api.call.com/#{method}/#{id}?key=API_KEY"
    else
      "http://api.call.com/#{method}?key=API_KEY"
    end
  end

  def process_response_body(body) do
    body
    |> Poison.decode!(as: %{"items" => [%Item{}]})
    |> Map.fetch!("items")
  end

В process_response_body, как я могу проверить свойство items в ответе JSON, и, если оно не существует, обработать его по-другому?

1 ответ

Решение

Я бы просто расшифровал результат и написал бы многогранную функцию, чтобы упаковать ее в ваши объекты. Что-то вроде:

def process_response_body(body) do
  body
  |> Poison.decode!
  |> unpack
end

def unpack(%{"items" => items}) do
  Enum.map(items, &struct(Item, &1))
end
def unpack(%{"item" => item}), do: struct(Item, item)

Или с делом:

body
|> Poison.decode!
|> case do
  %{"items" => items} -> Enum.map(items, &struct(Item, &1))
  %{"item" => item} -> struct(Item, item)
end
Другие вопросы по тегам