Skip to content

Diversión a la Rust: ¡Construyendo tu Primer Servidor Web en Rust! 🦀

Posted on:12 de abril de 2020 at 19:00

“Diversión a la Rust: ¡Construyendo tu Primer Servidor Web en Rust! 🦀”

¡Empecemos! 🚀

Hoy, nos embarcamos en una emocionante aventura para crear un sencillo servidor web en Rust que sirve una página HTML básica. En las secciones siguientes, profundizaremos en la adición de enrutamiento para crear una API completa. ¡Arremanguémonos y empecemos! 💼

Paso Uno: Configurando tu Proyecto 🛠️

Lo primero, abre tu terminal y ejecuta:

cargo new --bin mi-primer-servidor-web

Una vez que el comando termine de ejecutarse, verás la siguiente salida en la consola:

cargo new --bin mi-primer-servidor-web
    Created binary (application) 'mi-primer-servidor-web' package

Este comando ha creado un binario ejecutable para un proyecto “Hola Mundo” en Rust. Como seguramente sabes, Cargo es el gestor de paquetes de Rust. El comando “new” se utiliza para crear un nuevo proyecto, y “—bin” especifica que se trata de un proyecto de binario ejecutable. El proyecto se llama “mi-primer-servidor-web”.

¡Abre tu Editor de Código Preferido! 🖋️

Yo uso Visual Studio Code (VsCode) como mi editor de código. Puedes encontrar más información aquí.

Ahora, echemos un vistazo a lo que ha generado el comando anterior. 🧐

Estructura de un proyecto Rust recién creado

Como puedes ver, ha creado una estructura con un archivo .gitignore, una carpeta “src” y un archivo Cargo.toml. Si no estás seguro de para qué sirve el archivo Cargo.toml, te recomiendo que leas la primera entrada de mi post sobre ¿Por qué Rust?, donde explico estos conceptos.

Ahora, exploremos la carpeta “src”. 📁

Estructura de un proyecto Rust recién creado, carpeta "src"

Notarás que solo hay un archivo .rs adentro, que es la extensión de los archivos fuente de Rust. Este archivo contiene un simple programa “Hola Mundo”. 🌍

fn main() {
    println!("¡Hola, mundo!");
}

¡Ahora, Manos a la Obra! 👨‍💻

El primer paso es agregar las dependencias que necesitamos a nuestro proyecto. Necesitaremos:

Como expliqué en mi post anterior, las dependencias se enumeran en el archivo Cargo.toml de la siguiente manera. 📦

[dependencies]
iron = "0.6.1"

Cada línea bajo “dependencies” especifica un crate (paquete) de crates.io y la versión que deseamos utilizar. Al especificar una versión fija para la dependencia, garantizamos que nuestro código siga funcionando incluso si se realizan actualizaciones en esas dependencias, evitando posibles problemas de compatibilidad.

Si especificas: 🔄

[dependencies]
iron = "*"

Siempre buscará la versión más nueva de esa dependencia, lo que puede llevar a posibles incompatibilidades con tu código.

Solo listas los paquetes que utilizas directamente, y Cargo se encarga de descargar las dependencias necesarias para esos paquetes. 📦

¡Ahora, Sumérgete en el Código! Abre el archivo “main.rs” 📝

extern crate iron;

use iron::mime::Mime;
use iron::prelude::*;
use iron::status;

fn main() {
    println!("Servidor escuchando en http://localhost:3000");

    Iron::new(get_welcome).http("localhost:3000").unwrap();
}

fn get_welcome(_request: &mut Request) -> IronResult<Response> {
    let mut response = Response::new();
    let content_type = "text/html".parse::<Mime>().unwrap();

    response.set_mut(status::Ok);
    response.set_mut(content_type);

    response.set_mut(
        r#"
        <title>Mi Primer Servidor Web en Rust</title>
        <h1>¡Bienvenido a mi servidor web en Rust! :)</h1>
        "#,
    );

    Ok(response)
}

Ahora, desg

losemos lo que hace cada parte. No te preocupes si no tiene sentido al principio; lo revisaremos paso a paso. 🤷‍♂️

La siguiente línea importa el crate que hemos añadido como dependencia: 📦

extern crate iron;

Las tres líneas siguientes simplifican nuestro código y nos permiten escribir espacios de nombres más cortos para los elementos importados: ✏️

use iron::mime::Mime;
use iron::prelude::*;
use iron::status;

Cada archivo “main.rs” en Rust debe tener una función main para ejecutarse. Las funciones en Rust se definen con la palabra clave fn, seguida del nombre de la función.

Nos centraremos en las partes más interesantes: 🎯

fn main() {
    println!("Servidor escuchando en http://localhost:3000");

    Iron::new(get_welcome).http("localhost:3000").unwrap();
}

Este código configura una nueva instancia de Iron, pasando una función (que definiremos más adelante) como argumento. Luego, especifica que el servidor debe ejecutarse en localhost en el puerto 3000. El método unwrap maneja los errores y devuelve un mensaje de error si algo sale mal, asegurando que tengamos nuestra instancia de Iron en funcionamiento.

Ahora, exploremos la función get_welcome, que recibe una Request como parámetro: 👨‍💻

fn get_welcome(_request: &mut Request) -> IronResult<Response> {
    let mut response = Response::new();
    let content_type = "text/html".parse::<Mime>().unwrap();

    response.set_mut(status::Ok);
    response.set_mut(content_type);

    response.set_mut(
        r#"
        <title>Mi Primer Servidor Web en Rust</title>
        <h1>¡Bienvenido a mi servidor web en Rust! :)</h1>
        "#,
    );

    Ok(response)
}

En esta función, comenzamos creando un nuevo objeto Response. Luego, especificamos el tipo de contenido como “text/html” utilizando el tipo Mime y configuramos el código de estado HTTP en 200 (lo que indica una respuesta exitosa). También configuramos el tipo de contenido y el cuerpo de la respuesta, que es una página HTML sencilla con un título y un mensaje de bienvenida. 📃

¡Es hora de poner lo aprendido a prueba! 🚀