PlugLoopback (plug_loopback v0.1.0)

View Source

A set of utils to programmatically call your own endpoints

It happens that sometimes you need to programmatically call your own endpoint (for instance Phoenix endpoint). One could use an HTTP client locally calling your own deployed instance, but it's cumbersome, hard to test and comes with an overhead.

This library intends to provide with a set of function to directly call your endpoint. It is very similar to Phoenix.ConnTest and reimplements a Plug adapter for this purpose.

You can form a new request from a Phoenix endpoint:

MyAppWeb.Endpoint
|> PlugLoopback.from_phoenix_endpoint()
|> PlugLoopback.get("/some/path", [{"some", "header"}])
|> Plug.Conn.put_req_header("another", "header")
|> PlugLoopback.run()

or replay any Plug.Conn{}:

conn
|> PlugLoopback.replay()
|> PlugLoopback.run() # Here is a very good opportunity to create an infinite loop!

Warning

For some very good reasons, you must run these commands in their own process. Do not run it in a process that already processed a %Plug.Conn{}.

Summary

Functions

Shortcut for request/1 with "DELETE" method

Creates a new fresh conn from a Phoenix endpoint

Shortcut for request/1 with "GET" method

Shortcut for request/1 with "HEAD" method

Shortcut for request/1 with "PATCH" method

Shortcut for request/1 with "POST" method

Shortcut for request/1 with "PUT" method

Creates a new fresh conn ready to request from another conn

Runs a request created by functions of this module

Functions

delete(conn, path, headers \\ [], body \\ nil)

@spec delete(Plug.Conn.t(), binary(), Plug.Conn.headers(), binary() | nil) ::
  Plug.Conn.t()

Shortcut for request/1 with "DELETE" method

from_phoenix_endpoint(endpoint)

@spec from_phoenix_endpoint(module()) :: Plug.Conn.t()

Creates a new fresh conn from a Phoenix endpoint

Peer data IP address is set to 127.0.0.1.

After calling this function, you need to form a request with get/4, post/4, put/4, patch/4 head/4, delete/4 or the generic request/5.

get(conn, path, headers \\ [], body \\ nil)

@spec get(Plug.Conn.t(), binary(), Plug.Conn.headers(), binary() | nil) ::
  Plug.Conn.t()

Shortcut for request/1 with "GET" method

head(conn, path, headers \\ [], body \\ nil)

@spec head(Plug.Conn.t(), binary(), Plug.Conn.headers(), binary() | nil) ::
  Plug.Conn.t()

Shortcut for request/1 with "HEAD" method

patch(conn, path, headers \\ [], body \\ nil)

@spec patch(Plug.Conn.t(), binary(), Plug.Conn.headers(), binary() | nil) ::
  Plug.Conn.t()

Shortcut for request/1 with "PATCH" method

post(conn, path, headers \\ [], body \\ nil)

@spec post(Plug.Conn.t(), binary(), Plug.Conn.headers(), binary() | nil) ::
  Plug.Conn.t()

Shortcut for request/1 with "POST" method

put(conn, path, headers \\ [], body \\ nil)

@spec put(Plug.Conn.t(), binary(), Plug.Conn.headers(), binary() | nil) ::
  Plug.Conn.t()

Shortcut for request/1 with "PUT" method

replay(conn)

@spec replay(Plug.Conn.t()) :: Plug.Conn.t()

Creates a new fresh conn ready to request from another conn

State is reinitialized so that the returned conn is cleaned to be requested again.

If a Phoenix endpoint was used, then it is recognized and the result conn can be run with run/1. Otherwise you need to call the next plug yourself, like:

conn
|> PlugLoopback.replay()
|> MyOtherPlugModule.call(opts)

or if the conn is from a phoenix endpoint:

conn
|> PlugLoopback.replay()
|> # modify the conn, for instance by setting new request headers
|> PlugLoopback.run()

Peer data is copied from the original conn.

request(conn, method, path, req_headers \\ [], body \\ nil)

@spec request(
  Plug.Conn.t(),
  Plug.Conn.method() | atom(),
  binary(),
  Plug.Conn.headers(),
  binary() | nil
) :: Plug.Conn.t()

Readies a conn for requesting

This function sets the necessary information to make a request: method, path, headers and body.

When setting a body, make sure to encode it to a binary and to set the correct content-type header. This library doesn't do it for you.

Example

MyAppWeb.Endpoint
|> PlugLoopback.from_phoenix_endpoint()
|> PlugLoopback.post("/api/user", [{"content-type", "application/json"}, JSON.encode!(data)])
|> PlugLoopback.run()

run(conn)

@spec run(Plug.Conn.t()) :: Plug.Conn.t()

Runs a request created by functions of this module