ya que "data" ha sido reemplazado por app_data, cabe mencionar que no funcionan de la misma manera:
el equivalente de
data(pool.clone())
sería:
app_data(web::Data::new(pool.clone()))
Conectar una base de datos a un servidor web en Rust puede sonar complejo, pero con Actix se vuelve manejable si entiendes el flujo correcto. Aquí aprenderás cómo mostrar datos de PostgreSQL en Actix usando Rust, validar errores con match y devolver respuestas legibles al navegador. Es contenido pensado para quien ya instaló Actix y necesita dar el siguiente paso: leer registros y enviarlos al frontend.
Cómo preparar la ruta index y el pool de conexiones en Actix
Antes de tocar la base de datos, necesitas dejar lista la ruta principal y un mecanismo que mantenga vivas las conexiones.
Lo primero es renombrar la función del handler como index, que es el nombre convencional para la ruta raíz. Después se define un nuevo tipo público llamado dbPool, que actúa como contenedor de conexiones gestionadas por r2d2.
¿Qué es un pool de conexiones? Es un contenedor que mantiene varias conexiones abiertas a la base de datos para reutilizarlas. Así evitas abrir y cerrar conexiones en cada petición, lo que mejora el rendimiento.
Piensa en el pool como un arca: dentro viven los connection managers listos para responder cuando una petición los necesite. Esta analogía ayuda a entender por qué la sintaxis de r2d2 parece envolver tantas capas: cada una protege y administra el acceso concurrente.
Cómo inyectar el pool en el handler
Al handler index se le agrega un parámetro de entrada llamado pool, tipado como web::Data<dbPool>. Ese web::Data referencia el data que se registró previamente al iniciar el servidor, y le da al endpoint acceso directo a la base de datos.
Dentro del handler se crea la variable let conn = pool.get(), y si falla, se devuelve el mensaje "Problems fetching the database".
Cómo ejecutar una query con web::block y validar errores con match
La lectura de datos en Actix no se hace directamente: hay que bloquear el thread para evitar condiciones de carrera.
Esto se logra con web::block, una utilidad propia del framework que aísla la ejecución de la query. Dentro se hace un move y se corre la consulta Posts.load, especificando el tipo Post y pasándole la conexión conn obtenida del pool.
El resultado pasa por un match con dos ramas:
¿Por qué usar match en Rust para queries? Porque las operaciones que pueden fallar devuelven un
Result. Elmatchte obliga a manejar tanto el caso exitoso como el error, evitando que tu servidor crashee silenciosamente.
Al no llevar punto y coma al final, el match se convierte en el valor de retorno de la función. Si vienes de otro lenguaje y eso te confunde, puedes escribir return explícito con punto y coma; ambas formas son válidas.
Errores comunes al conectar Actix con PostgreSQL
Durante la implementación aparecen tropiezos típicos que conviene anticipar.
schema del proyecto.self::models::Post.await al final del bloque web::block, ya que se trata de una operación asíncrona que espera respuesta del thread bloqueado..env, lo que provoca un panic indicando que la conexión no fue posible.Resolver estos detalles permite que el servidor compile y responda en el navegador con el mensaje "We have found data".
Cómo mostrar los posts reales en el navegador con format
Devolver "hemos encontrado datos" no aporta valor. El siguiente paso es mostrar el contenido real de cada post.
Dentro de la rama Ok del match, se abren llaves para ejecutar varias instrucciones. Primero se usa println! con el truco de pasar data para depurar en consola y confirmar que llega un arreglo de posts.
Luego se itera con for post in data, construyendo una variable response de tipo String que arranca vacía. En cada vuelta se reasigna usando la macro format!, que es la forma idiomática en Rust de concatenar strings con interpolación de valores.
Dentro de format! se inserta post.title y post.body, de modo que la respuesta acumule el contenido legible de cada registro.
Por qué format es mejor que println para devolver respuestas
Después de probar, hay un patrón más limpio: usar directamente format! como valor de retorno del handler.
println! imprime en la terminal del servidor pero no devuelve nada útil al cliente. format! hace lo mismo en términos de interpolación, pero retorna un String que Actix puede enviar como respuesta HTTP.
Así, al recargar el navegador, aparecen el título, el slug y el body del post directamente en la pantalla. Si tuvieras un frontend consumiendo ese endpoint, ya podría leer y renderizar los posts sin lógica adicional en el servidor.
Conceptos y herramientas clave de la clase
Estos son los elementos técnicos que vale la pena fijar para seguir avanzando con Actix y Diesel.
Result que devuelven las operaciones que pueden fallar.String, ideal para construir respuestas HTTP.web::block porque la operación es asíncrona.¿Ya lograste mostrar tus propios posts en el navegador? Cuéntame en los comentarios qué error te apareció primero y cómo lo resolviste.
Conectar una base de datos a un servidor web en Rust puede sonar complejo, pero con Actix se vuelve manejable si entiendes el flujo correcto. Aquí aprenderás cómo mostrar datos de PostgreSQL en Actix usando Rust, validar errores con match y devolver respuestas legibles al navegador. Es contenido pensado para quien ya instaló Actix y necesita dar el siguiente paso: leer registros y enviarlos al frontend.
Antes de tocar la base de datos, necesitas dejar lista la ruta principal y un mecanismo que mantenga vivas las conexiones.
Lo primero es renombrar la función del handler como index, que es el nombre convencional para la ruta raíz. Después se define un nuevo tipo público llamado dbPool, que actúa como contenedor de conexiones gestionadas por r2d2.
¿Qué es un pool de conexiones? Es un contenedor que mantiene varias conexiones abiertas a la base de datos para reutilizarlas. Así evitas abrir y cerrar conexiones en cada petición, lo que mejora el rendimiento.
Piensa en el pool como un arca: dentro viven los connection managers listos para responder cuando una petición los necesite. Esta analogía ayuda a entender por qué la sintaxis de r2d2 parece envolver tantas capas: cada una protege y administra el acceso concurrente.
Al handler index se le agrega un parámetro de entrada llamado pool, tipado como web::Data<dbPool>. Ese web::Data referencia el data que se registró previamente al iniciar el servidor, y le da al endpoint acceso directo a la base de datos.
Dentro del handler se crea la variable let conn = pool.get(), y si falla, se devuelve el mensaje "Problems fetching the database".
La lectura de datos en Actix no se hace directamente: hay que bloquear el thread para evitar condiciones de carrera.
Esto se logra con web::block, una utilidad propia del framework que aísla la ejecución de la query. Dentro se hace un move y se corre la consulta Posts.load, especificando el tipo Post y pasándole la conexión conn obtenida del pool.
El resultado pasa por un match con dos ramas:
¿Por qué usar match en Rust para queries? Porque las operaciones que pueden fallar devuelven un
Result. Elmatchte obliga a manejar tanto el caso exitoso como el error, evitando que tu servidor crashee silenciosamente.
Al no llevar punto y coma al final, el match se convierte en el valor de retorno de la función. Si vienes de otro lenguaje y eso te confunde, puedes escribir return explícito con punto y coma; ambas formas son válidas.
Durante la implementación aparecen tropiezos típicos que conviene anticipar.
schema del proyecto.self::models::Post.await al final del bloque web::block, ya que se trata de una operación asíncrona que espera respuesta del thread bloqueado..env, lo que provoca un panic indicando que la conexión no fue posible.Resolver estos detalles permite que el servidor compile y responda en el navegador con el mensaje "We have found data".
Devolver "hemos encontrado datos" no aporta valor. El siguiente paso es mostrar el contenido real de cada post.
Dentro de la rama Ok del match, se abren llaves para ejecutar varias instrucciones. Primero se usa println! con el truco de pasar data para depurar en consola y confirmar que llega un arreglo de posts.
Luego se itera con for post in data, construyendo una variable response de tipo String que arranca vacía. En cada vuelta se reasigna usando la macro format!, que es la forma idiomática en Rust de concatenar strings con interpolación de valores.
Dentro de format! se inserta post.title y post.body, de modo que la respuesta acumule el contenido legible de cada registro.
Después de probar, hay un patrón más limpio: usar directamente format! como valor de retorno del handler.
println! imprime en la terminal del servidor pero no devuelve nada útil al cliente. format! hace lo mismo en términos de interpolación, pero retorna un String que Actix puede enviar como respuesta HTTP.
Así, al recargar el navegador, aparecen el título, el slug y el body del post directamente en la pantalla. Si tuvieras un frontend consumiendo ese endpoint, ya podría leer y renderizar los posts sin lógica adicional en el servidor.
Estos son los elementos técnicos que vale la pena fijar para seguir avanzando con Actix y Diesel.
Result que devuelven las operaciones que pueden fallar.String, ideal para construir respuestas HTTP.web::block porque la operación es asíncrona.¿Ya lograste mostrar tus propios posts en el navegador? Cuéntame en los comentarios qué error te apareció primero y cómo lo resolviste.
ya que "data" ha sido reemplazado por app_data, cabe mencionar que no funcionan de la misma manera:
el equivalente de
data(pool.clone())
sería:
app_data(web::Data::new(pool.clone()))
Al abrir el navegador me aparece el siguiente mensaje
Requested application data is not configured correctly. View/enable debug logs for more details.
Que puedo hacer ?
Haciendo esto logre el primer intento que hizo Hector si se quisiera hacer string interpolation
let mut respuesta = String::new();
for post in data.unwrap() {
let new_post = format!("{}\n{}\n", post.title, post.body);
respuesta.push_str(&new_post);
}
Me pueden ayudar, tengo un error que no puedo resolver, al usar el &conn

return HttpResponse::Ok().body(format!("{:?}",data)); | ^^^^ cannot be formatted using
Post{:?}Si alguien se encuentra con el error: "process didn't exit successfully: target\debug\blog-platzi.exe (exit code: 3)" en Windows 10/11, hay una solución reemplazando un .dll que lo explican en:
/ada
/ada
#[actix_web::main]
async fn main()->std::io::Result<()> {
dotenv().ok();
let db_url = env::var("DATABASE_URL").expect("db url variable no encontrada");
let conn = ConnectionManager::<PgConnection>::new(db_url);
let pool = Pool::builder().build(conn).expect("error ");
HttpServer::new(move||{
App::new().service(index).app_data(web::Data::new(pool.clone()))
}).bind(("0.0.0.0",3006)).unwrap().run().await
}
Ya no es gratis HEROKU , deben de actualizar el curso.