The beauty of LiveView
Lately we have been working on Bytepack to help developers deliver and sell packages to companies and enterprises.
In Bytepack, authors can push new packages at any time. Publishing said packages is done with your usual package manager tool, such as mix hex.publish
in Elixir or npm publish
for Node.js. Once you call these commands, the request goes to specific endpoints that implement the Hex.pm and npm APIs.
The specific steps are shown in our “New package” page:
The /packages/new
route is a Phoenix LiveView that looks like this:
defmodule BytepackWeb.PackageLive.New do
use BytepackWeb, :live_view
def mount(params, session, socket) do
socket = authenticate(socket, session)
{:noreply, socket}
end
def render(assigns) do
~L"""
...HTML template...
"""
end
end
Nothing special so far. But here is where LiveView is a big deal.
To improve the user experience, we also wanted to automatically update the browser with the package information whenever the user publishes it. Implementing this functionality in LiveView requires three changes.
First we broadcast an event whenever a package is created to a “package:new” topic under the user:
Phoenix.PubSub.broadcast(
Bytepack.PubSub,
"user:#{user.id}:package:new",
{:published, package.id}
)
Back in PackageLive.New
, we change mount/3
to also subscribe to said topic:
def mount(params, session, socket) do
socket = authenticate(socket, session)
if connected?(socket) do
Phoenix.PubSub.subscribe(
Bytepack.PubSub,
"user:#{socket.assigns.current_user.id}:package:new"
)
end
{:noreply, authenticate(socket, session)}
end
and then write a clause to handle said events:
def handle_info({:published, package_id}, socket) do
{:noreply, live_redirect(socket, to: "/packages/#{package_id}")}
end
And that’s it! Now we redirect the browser to the newly created package page whenever the package is published.
We didn’t have to:
- manually establish WebSockets or long-polling connections
- create a separate endpoint to send requests to
- define a specific JSON payload between client/server
- write any front-end glue code
- setup third-party dependencies for pubsub, such as Redis, nor anything else to run at scale
- etc
Compared to what others have built with LiveView, this is absolutely trivial. However, the fact we can set this up in less than 2 minutes is that excites me!
LiveView comes with its own integrated testing story too. We can test everything from the comfort of Elixir, without a need to bring heavy-hitters such as Selenium or any webdriver.
To run in development, we only need to start our Phoenix server. We don’t need external tooling in production either. We can deploy this to Fly.io or Gigalixir, configure clustering, and everything just works across multiple nodes.
While this is a very limited sample of what LiveView can do, it highlights the beauty of its model and, perhaps more importantly, it shows all of the things we don’t have to manage nor worry about. At the end of the day, the Bytepack team can focus more on the user experience than we would otherwise, thanks to LiveView’s accessibility.