Search code examples
jsonelixirphoenix-frameworkhttpoison

Return JSON after REST call in Phoenix endpoint


I am learning Elixir and Phoenix, I'm building a side project that needs to query Github's APIs.

This is the module that performs the call

defmodule Github do

  use HTTPoison.Base

  def process_url(url) do
    "https://api.github.com/" <> url
  end

  def process_response_body(body) do
    body
    |> Poison.decode!
    |> Enum.map(fn({k, v}) -> {String.to_atom(k), v} end)

  end

end

and this is the Controller that answers to a GET on "/api/github/search"

defmodule MyApp.GithubController do

  use MyApp.Web, :controller
  require Github

  def search(conn, _params) do
    json conn, search_repositories
  end

  def search_repositories() do

    url = "search/repositories?q=language:javascript&sort=stars&order=desc"
    Github.get! url
  end

end

I get an error page from Phoenix which says at the top

unable to encode value: {:total_count, 2389278}

So something is working, I am actually calling Github's API, but for some reason I'm missing a step, I've followed the example here https://github.com/edgurgel/httpoison#wrapping-httpoisonbase

Any help / hint is highly appreciated!


Solution

  • Not sure what your expected result is, but I assume you just want to return from your controller the complete response from Github as JSON. Just let Poison handle the decoding, no need to process it further.

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

    Your missing piece is the fact that get! doesn't return the JSON, but a %HTTPoison.Response struct as can be seen in the first usage example here https://github.com/edgurgel/httpoison

    The struct contains your processed body, headers and the status code. You can use pattern matching to extract your json and return it:

    def search_repositories() do
      url = "search/repositories?q=language:javascript&sort=stars&order=desc"
      %HTTPoison.Response{:body => json, :headers => headers, :status_code => code} = Github.get! url
      IO.inspect headers
      IO.inspect code
      json
    end