Phoenix
Phoenix is a full-stack web development framework for Elixir.
Electric and Phoenix
Electric is developed in Elixir and provides an Elixir client. We've leveraged this to develop a batteries-included Phoenix integration for:
- front-end sync: into a front-end client from a Postgres-backed Phoenix application
- LiveView sync: into Phoenix LiveView from Postgres in realtime via Phoenix.Streams
Electric.Phoenix
is published on Hex as hex.pm/packages/electric_phoenix.
Inspiration
It was inspired by josevalim/sync
. You can read José's original design document.
How to use
Front-end sync
Phoenix is a general framework that provides a number of different methods to get data from the server to the client. These include exposing REST APIs and using Absinthe to expose a GraphQL endpoint.
Electric.Phoenix
provides an alternative method: exposing Shapes that sync data directly from Postgres into the client. With this, shapes are exposed and configured in your Phoenix Router. For example, here we expose a predefined shape of all visible todos, deriving the shape definition from an Ecto query using your existing data model:
defmodule MyAppWeb.Router do
use Phoenix.Router
alias MyApp.Todos.Todo
scope "/shapes" do
pipe_through :browser
get "/todos", Electric.Phoenix.Gateway.Plug,
shape: Electric.Client.shape!(Todo, where: "visible = true")
end
end
Because the shape is defined in your Router, it can use Plug middleware for authorisation. See Parameter-based shapes for more details.
LiveView sync
Phoenix LiveView allows you to develop interactive web applications in Elixir/Phoenix, often without writing any front-end code.
LiveView provides a primitive, called Phoenix.Streams that allows you to stream data into a LiveView. Electric.Phoenix
provides a wrapper around this to automatically stream a Shape into a LiveView.
The key primitive is a live_stream/4
function that wraps Phoenix.LiveView.stream/4
to provide a live updating collection of items.
def mount(_params, _session, socket) do
socket =
Electric.Phoenix.live_stream(
socket,
:visible_todos,
from(t in Todo, where: t.visible == true)
)
{:ok, socket}
end
This makes your LiveView applications real-time. In fact, it allows you to build interactive, real-time multi-user applications straight out of your existing Ecto schema, without writing any JavaScript at all 🤯
More details
For more details and full documentation see hexdocs.pm/electric_phoenix.
Help wanted Good first issue
We have an open GitHub issue tracking this if you'd like to contribute an equivalent integration for other server-side frameworks, such as Rails, Laravel, Django, etc.
Please leave a comment or ask on Discord if you'd like any pointers or to discuss how best to approach this.