BookinglyTech News
Software

Fitz genera el endpoint y el stub de fetch desde un solo decorador @rpc

El lenguaje marca una función async con @rpc y el compilador emite las dos mitades: la ruta POST en el servidor y la llamada fetch en el cliente WASM, con el mismo tipo compartido.

3 min de lecturaDev.to0 vistas

Fitz deja marcar una función async con @rpc y llamarla desde un componente .fitzv que compila a WebAssembly como si fuera local: get_user(42).await?. El compilador escribe las dos mitades a partir de esa declaración —el endpoint POST /__rpc/get_user en el servidor y un stub de fetch en el cliente— compartiendo la misma definición de tipos. El autor lo presenta como la parte 7 de su serie FitzLiveViews y el ejemplo ejecutable está en el repositorio.

Las entregas anteriores mostraban un componente .fitzv compilando de dos maneras: a HTML renderizado en servidor sobre un WebSocket y a una SPA de WebAssembly independiente. El problema del segundo caso es que un componente en el navegador es una isla: leer una base de datos o validar un token tiene que pasar en el servidor, y el puente habitual es plomería a mano.

Qué emite el compilador

Del lado servidor, fitz build --bin server monta la función como POST /__rpc/get_user en el puerto 3838. El cuerpo es un objeto JSON con un campo por parámetro, cada uno se deserializa de su campo, y el Result<T> sale como 200 con el JSON de T o como 500 con {"error": ...}. Todo reutiliza la cadena de @post: observabilidad, captura de pánicos incluida.

Del lado cliente, fitz build --bin web --target wasm-client emite la función importada como un stub fetch asíncrono, y el cuerpo original no se transpila al WASM. El stub serializa los argumentos, hace POST al mismo origen —así la cookie de sesión viaja sola— y mapea la respuesta a Result<T>. Como el manejador de evento ahora usa .await, el compilador lo parte en un wrapper síncrono y un worker asíncrono con spawn_local, y el componente se vuelve a renderizar cuando llega la respuesta. El crate cliente compila a un .wasm real con wasm-pack.

La demo es una SPA de dos botones más un binario de servidor, probada en Chrome según el autor: al pulsar uno vuelve un saludo del servidor y al pulsar el otro se pide un User que se deserializa y se pinta en pantalla.

En qué se diferencia y dónde está el límite

Las funciones de servidor no son nuevas: Next.js Server Actions, los loaders de Remix, SvelteKit con +page.server, tRPC o Phoenix cubren el mismo patrón. Fitz promete hacerlo sin paso de infraestructura —sin directiva use server, sin router de tRPC, sin generador de código—, con la misma definición de tipo compilada a un struct nativo y a un struct WASM, sin dependencias externas y con un único lenguaje en ambos extremos. Son afirmaciones del autor del proyecto, no de un tercero que lo haya medido.

Quedan bordes reconocidos. Un tipo nominal que cruza el cable hay que importarlo también en el .fitzv. El control de acceso sobre el endpoint generado mediante anotaciones tipo @authenticated o @admin es refinamiento posterior al MVP: por ahora se valida el token dentro del cuerpo de la función. Y el re-render ocurre una sola vez, al llegar la respuesta, así que cualquier intermedio de "cargando" espera a una reactividad más fina.

Lo siguiente en la hoja de ruta es la hidratación SSR: el mismo .fitzv renderizado en servidor para el primer pintado, y luego el runtime WASM tomando el control del DOM existente, incluido el estado que dejaron las llamadas @rpc.