Glass

Glass is a small library which provides a way to transparently proxy function calls in a pluggable fashion.

Installation

Add :glass to the list of dependencies in mix.exs:

def deps do
  [
    {:glass, "~> 0.1.0"}
  ]
end

About

This is immediately useful if you’re working with multiple applications potentially deployed in different releases/environments but need to call functions between them.

Usually, you could do this via the built-in :rpc or :erpc modules (amongst others), but this requires ceremony and boilerplate to set up and maintain.

Glass aims to live up to its name, and the idea that the BEAM is network-transparent, by completely hiding the fact that you’re not just calling a local function.

Usage

Once installed, you can use Glass as simply as adding the following to your code:

# 1) Setup and initialize `Glass`
use Glass

# 2) Define a `GlassProxy` for the target module, which for this example, we can
#    imagine is in another Elixir application which is bundled in the same umbrella
#    project as the current application, but is *released separately* in a production
#    environment so *we can't directly call functions in it*.
defglass ReportService, via: Glass.Methods.RPC

# 3) Be blown away by `Glass` letting you call these functions directly...
def accounts_receivable_report do
  current_user()
  |> MyApp.Accounting.accounts_receivable()
  |> ReportService.to_excel!()
end

Configuration

Glass is designed to be pluggable and extensible, and comes with a few built-in methods for proxying function calls between modules.

Built-in Methods

Custom Methods

You can also define your own method for proxying function calls by implementing the Glass.Method behaviour. If you want to customize the way Glass proxies function calls, you can define your own module and pass it as the :via option to defglass.

defmodule MyApp.Tupleize do
  @behaviour Glass.Method

  @impl Glass.Method
  def handle_proxy(module, function, args) do
    {module, function, args}
  end
end

defmodule MyApp.Users do
  use Glass

  defglass ReportService, via: MyApp.Tupleize

  ...

  def users_report do
    current_org()
    |> list_users()
    |> Enum.map(&build_report_rows/1)
    |> ReportService.to_csv!()
  end
end

iex(1)> MyApp.Users.users_report()
{ReportService, :to_csv!, [ ... ]}

Additional Configuration

Caveats

Future Work

License

Glass is released under the MIT License. See the LICENSE file for more information.