poteto / terraform

A simple plug for incrementally transforming an API into Phoenix. Check out the blog post:

Home Page:https://www.no.lol/2016-08-12-rise-from-the-ashes-incremental-apis-with-phoenix/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Terraforming with a request body?

digitalcora opened this issue · comments

Hi, first of all, thanks very much for this library! 😸 The concept seems very useful for our current project. However, we've encountered an issue with request bodies — they don't seem to be present by the time the connection reaches the terraformer.

With irrelevant details removed, the terraformer looks like this:

defmodule OurApp.Terraformer do
  use Plug.Router

  plug :match
  plug :dispatch

  @base_uri "http://localhost:4001"

  match _ do
    method = conn.method |> String.downcase |> String.to_atom
    uri = @base_uri |> URI.merge(conn.request_path) |> URI.to_string
    {:ok, request_body, conn} = read_body(conn)
    # When inspected here, the request body is always an empty string!
    # IO.inspect(request_body)
    conn = fetch_query_params(conn)
    options = [params: conn.query_params |> Map.to_list]

    response = HTTPoison.request!(method, uri, request_body, conn.req_headers, options)

    conn = %{conn | resp_headers: response.headers}
    send_resp(conn, response.status_code, response.body)
  end
end

It's possible this is related to phoenixframework/phoenix#459, although I hope not because it seems like that would be extremely complicated to work around. In any case, I'd love to know if there's example code someplace where terraform is being used with request bodies — all the code I can find uses only GET requests.

I also would be interested in knowing this. Has anyone figured this out yet?

Same issue here :(

Is this project still active?

For anyone who comes across this issue and gets stuck, you can access the body from a POST or PUT request via conn.body_params. One caveat that had me stuck for longer than I'd care to admit, if you POST or PUT with an empty body, then the body params in the conn struct will be a Plug.Conn.Unfetched struct, appearing as if the body was not loading. Hope this helps someone!

Thanks @John-Goff!

@John-Goff This was a while ago, but I believe in my case it was important to pass the raw request body through the terraformer exactly as-is, rather than getting the parsed body_params and rendering it back into a string.

Luckily it appears Plug has since added a body_reader option that serves this use case. The issue I linked in the OP has an example of its use: phoenixframework/phoenix#459 (comment)