Vamos a dar un vistazo a una de las opciones que el ecosistema de Rust nos brinda para el desarrollo de aplicaciones web.

Se asume que el lector ya conoce bien el lenguaje de programación Rust y que ya cuenta con un entendimiento básico de los fundamentes del desarrollo de aplicaciones web.

Rocket

Rocket, creado por Sergio Benitez, es un marco de trabajo para aplicaciones web que incorpora los elementos primitivos para el desarrollo de servidores y aplicaciones web con Rust. Rocket se enfoca en facilitar el ciclo de vida de las aplicaciones web y lo hace ayudando en cuatro áreas: el ruteo, la validación, el pre-procesamiento de peticiones, y el pos-procesamiento de respuestas.

Las tres filosofías de Rocket

  • Las declaraciones de funciones y tipos de parámetros deben contener toda la información indispensable para validar y procesar una solicitud.
  • El tipado de información al manejar solicitudes es obligatorio. Como la web y HTTP usan cadenas de texto, los valores dentro de las solicitudes y las respuestas deben ser transformados al tipo de datos que les corresponde. Rocket se hace cargo.
  • Las decisiones no deben forzarse. En otras palabras, Rocket no es una caja cerrada con todos sus elementos ocultos dentro de ella, los componentes para integrar la solución son opcionales. Plantillas, serialización, sesiones y otros componentes son acoplables e intercambiables.

Ejercicio: Hola, mundo

Vamos a crear un proyecto Rust con la herramienta Cargo. Necesitamos una terminal para introducir comandos:

cargo new --bin hola-rocket

Rocket requiere el uso de la versión nightly de Rust. Vamos a entrar en el nuevo directorio creado por Cargo y definiremos con Rustup que en este proyecto se use Rust nightly:

rustup override set nightly

Para asegurar el uso de la versión más reciente de Rust en este proyecto realizamos una actualización con Rustup y con Cargo:

rustup update && cargo update

Dependencias

Momento de trabajar con nuestro editor de código. En el archivo Cargo.toml vamos a agregar un par de dependencias para poder usar Rocket en nuestro proyecto:

[dependencies]
rocket = "0.3.17"
rocket_codegen = "0.3.17"

La primera ruta web de nuestra aplicación

Vamos a trabajar un poco para que nuestra nueva aplicación web nos responda “Hola, mundo” cuando visitemos la ruta “/” con nuestro navegador web. Para ello vamos a escribir un poco de código.

Nuestro archivo src/main_rs deberá quedar como sigue (hemos incluido comentarios que explican la finalidad de cada parte del código):

/*
    Vamos a necesitar un plugin de compilador para Rocket.
    Las siguientes dos líneas se hacen cargo de incluirlo.
*/
#![feature(plugin)]
#![plugin(rocket_codegen)]

// Incorporamos la biblioteca de Rocket en nuestro programa
extern crate rocket;

/*
    Declaración y función de una ruta index en "/", que va a responder
    una str estática diciendo "Hola, mundo".
*/
#[get("/")]
fn index() -> &'static str {
    "Hola, mundo"
}

/*
    Montaje de la ruta y la función index con Rocket.
    El servidor queda en espera de peticiones en "/".
*/
fn main() {
    rocket::ignite().mount("/", routes![index]).launch();
}

Ejecución de la aplicación

Volvamos a la terminal. “Lanzaremos” la aplicación con la herramienta Cargo:

cargo run

Esperamos un poco a la descarga de dependencias y compilación del programa. Si el proceso resulta exitoso tendremos en pantalla un mensaje como este:

🔧  Configured for development.
    => address: localhost
    => port: 8000
    => log: normal
    => workers: 8
    => secret key: generated
    => limits: forms = 32KiB
    => tls: disabled
🛰  Mounting '/':
    => GET /
🚀  Rocket has launched from https://localhost:8000

Para comprobar que la aplicación opera bien, en nuestro navegador web abrimos la URL https://localhost:8000 para ver nuestro “Hola, mundo”.

Para cerrar la aplicación, en la terminal usamos la combinación de teclas Control + c.

Un poco más, Hola + mi nombre

Demos un vistazo introductorio al trabajo con rutas y el paso de valores. Vamos a agregar una ruta “/hola”. También le daremos a la aplicación la capacidad de recibir una valor. En este caso, un nombre, por ejemplo: /hola/Mario. La respuesta de la aplicación será algo como “Hola, Mario”.

Necesitamos una nueva función de ruta en nuestro programa. Luego del cierre de la función index vamos a agregar la función hola:

#[get("/hola/<nombre>")]
fn hola(nombre: String) -> String {
    format!("Hola, {}", nombre)
}

En este ejemplo <nombre> será el parámetro que nos va a servir para construir el saludo que incluya un nombre.

Para montar esta ruta, dentro de la función main vamos a editar su única línea para que quede como sigue:

fn main() {
    rocket::ignite().mount("/", routes![index, hola]).launch();
}

Solamente hemos agregado el ítem hola, el nombre de nuestra nueva función, dentro de routes!.

En este punto podemos volver a ejecutar la aplicación con cargo run y en el navegador vamos a la ruta https://localhost:8000/hola/Mario (cambia Mario por el nombre que prefieras).

***

Esto fue un, muy escueto, vistazo inicial. Rocket contiene material suficiente para otro rato de aprendizaje. Hay mucho más que ver en relación al trabajo con solicitudes, respuestas, estados de la aplicación, pruebas, y configuración.

Si deseas continuar con esta exploración, el primer lugar para visitar es The Rocket Programming Guide.

Además, para éste y otros temas, es muy recomendable acercarse a la comunidad de Rust de tu región,  si la hay. Las comunidades de Rust en el mundo han ganado buena reputación en lo referente a su amabilidad, apertura y disposición para compartir conocimientos. Nos gustaría mucho contar contigo.