En pocas palabras
Framework web de Elixir para aplicaciones de servidor y experiencias interactivas con LiveView.
Qué problema resuelve
Complejidad de coordinar backend y cliente para interfaces con actualizaciones frecuentes.
Cuándo utilizarlo
Aplicaciones en tiempo real. Ejemplo: tablero operativo que refleja cambios de pedidos.
De la idea a la práctica
Funcionamiento, ejemplos y decisiones para pasar al siguiente nivel.
En el Radar compartido: Trial (valoración de la edición aportada).
Cómo funciona
Phoenix organiza rutas, canales y lógica web sobre la plataforma BEAM. LiveView mantiene estado en el servidor y envía actualizaciones de la interfaz mediante una conexión persistente.
Ejemplo de uso
Un LiveView recibe eventos de pedidos y actualiza la tabla del operador. El usuario filtra resultados y el servidor renderiza los cambios sin cargar toda la página.
La plataforma BEAM
Elixir se ejecuta en la máquina virtual de Erlang, diseñada para sistemas de telecomunicaciones con alta concurrencia y disponibilidad:
| Característica | Consecuencia práctica |
|---|---|
| Procesos ligeros (millones) | Cada conexión WebSocket o LiveView es un proceso aislado |
| Aislamiento de memoria | Un fallo en un proceso no afecta a otros |
| Supervisores | Reinician procesos caídos según una estrategia («let it crash») |
| Distribución nativa | Nodos que se comunican sin infraestructura adicional |
| Planificador preventivo | Una tarea pesada no bloquea a las demás |
Ejemplo: tabla en tiempo real con LiveView
defmodule KrediyaWeb.SolicitudesLive do
use KrediyaWeb, :live_view
alias Krediya.Originacion
def mount(_params, _session, socket) do
if connected?(socket), do: Phoenix.PubSub.subscribe(Krediya.PubSub, "solicitudes")
{:ok, stream(socket, :solicitudes, Originacion.listar_pendientes())}
end
def handle_info({:nueva_solicitud, solicitud}, socket) do
{:noreply, stream_insert(socket, :solicitudes, solicitud, at: 0)}
end
def handle_event("aprobar", %{"id" => id}, socket) do
{:ok, solicitud} = Originacion.aprobar(id, socket.assigns.current_user)
{:noreply, stream_insert(socket, :solicitudes, solicitud)}
end
def render(assigns) do
~H"""
<table>
<tbody id="solicitudes" phx-update="stream">
<tr :for={{dom_id, s} <- @streams.solicitudes} id={dom_id}>
<td>{s.cliente}</td>
<td>{s.monto}</td>
<td><button phx-click="aprobar" phx-value-id={s.id}>Aprobar</button></td>
</tr>
</tbody>
</table>
"""
end
end
Cuando otro proceso publica {:nueva_solicitud, s} en PubSub, todas las pantallas abiertas se actualizan. Streams evita mantener la lista completa en memoria del servidor.
Organización por contextos
Los generadores (mix phx.gen.live Originacion Solicitud solicitudes …) crean un contexto (Krediya.Originacion) que encapsula esquemas de Ecto y reglas de negocio, y una capa web que solo lo invoca. Es una aplicación directa de los bounded contexts.
Cuándo elegir Phoenix
| Encaja | Considerar alternativas |
|---|---|
| Paneles en tiempo real, chats, notificaciones, colaboración | Equipo sin experiencia en programación funcional |
| Muchas conexiones concurrentes con pocos servidores | Ecosistema de librerías muy específico de otro lenguaje |
| Interfaces interactivas sin mantener una SPA separada | Aplicaciones que deben funcionar sin conexión |
LiveView depende de la conexión: con latencias altas, usa phx-debounce, estados de carga y hooks de JavaScript para interacciones inmediatas. LiveDashboard y Telemetry ofrecen métricas del sistema desde el primer día.
Criterios de implementación
Diseñar reconexión y escalado de sesiones. Probar latencia y accesibilidad; usar hooks de cliente cuando la interacción requiera APIs locales del navegador.
Continúa en las fuentes
Documentación oficial para verificar detalles y explorar más.