De acuerdo a su sitio, Rocket es un framework web para Rust que hace que sea sencillo escribir aplicaciones web rápidas y seguras, sin sacrificar flexibilidad, usabilidad y el tipado fuerte.
La última versión disponible es la 0.4 publicada el 6 de Diciembre, el día que se lanzó Rust 2018, lo que garantiza su compatibilidad con la última edición del lenguaje. Rocket funciona con Rust Nightly.
Configuración
- Instalar Rust Nightly con rustup si no se tiene instalado.
$ rustup install nightly
- Crear un nuevo proyecto con Cargo.
$ cargo new hello_rocket
- Asignar Nightly al proyecto creado.
$ cd hello_rocket
$ rustup override set nightly
Estructura de directorios
La estructura del directorio de un proyecto desarrollo con Rocket es la siguiente:
- src
- static
- templates
- Cargo.toml
static es el directorio en el que se guardan las imágenes, archivos de JavaScript y hojas de estilo (CSS).
En el directorio templates se guardan las plantillas HTML.
Estos directorios deben crearse.
Templates
Rocket soporta dos sistemas de plantillas, Tera que está inspirado en Jinja2 y el lenguaje de plantillas de Django, y Handlebars.
¡Hola, mundo!
¡Es momento de crear el primer ejemplo con Rocket!
Cargo.toml
Agregar Rocket como dependencia al archivo Cargo.toml.
[package]
name = "hello_rocket"
version = "0.1.0"
authors = ["mattdark"]
edition = '2018'
[dependencies]
rocket = "0.4"
src/main.rs
Editar el archivo main.rs en src y colocar el código que mostrará el texto "¡Hola, mundo!" en el navegador.
#![feature(proc_macro_hygiene, decl_macro)]
#[macro_use] extern crate rocket;
#[get("/")]
fn index() -> &'static str {
"¡Hola, mundo!"
}
fn main() {
rocket::ignite().mount("/", routes![index]).launch();
}
Con la línea #![feature]
se le indica a Rust que se usarán funcionalidades del compilador disponibles en Nightly.
Se importa el crate de Rocket y todas sus macros al espacio de nombres mediante #[macro_use] extern crate rocket;
.
Se declara la función index
que mostrará el texto en el navegador y en la función principal main
se inicia el servidor de la aplicación.
Iniciando la aplicación
Se ejecuta el siguiente comando para iniciar el servidor de la aplicación.
$ cargo run
El comando anterior se encarga de descargar las dependencias del proyecto, de acuerdo a la información del archivo Cargo.toml, realiza la compilación, genera el binario correspondiente e inicia el servidor.
En caso de no haber error alguno, en la terminal aparece lo siguiente.
🔧 Configured for development.
=> address: localhost
=> port: 8000
=> log: normal
=> workers: 4
=> secret key: generated
=> limits: forms = 32KiB
=> keep-alive: 5s
=> tls: disabled
🛰 Mounting /:
=> GET / (index)
🚀 Rocket has launched from http://localhost:8000
Desde la barra de direcciones del navegador se accede a http://localhost:8000 y debe mostrar lo siguiente.
Routing
#[get("/world")] { // <- route attribute
fn world() -> &'static str { // <- request handler
"¡Hola, mundo!"
}
La función world
, declarada en el código anterior, corresponde al manejador de peticiones y está asociada a la ruta /world
, la cual recibirá peticiones de tipo GET
.
Mounting
Después de declarar una ruta, indicar el tipo de peticiones que recibirá y declarar la función que se encargará de manejar las peticiones, esta deberá montarse como se muestra a continuación.
fn main() {
rocket::ignite.mount("/hello", routes![world]).launch();
}
Lo anterior crea un nueva instancia de Rocket con la función ignite
y monta la ruta world
en la dirección /hello
. Las peticiones GET
a /hello/world
se redigirán a la función world
. El servidor de la aplicación se inicia con la función launch
.
Una vez iniciado el servidor, desde la barra de direcciones acceder a http://localhost:8000/hello/world y mostrará el siguiente texto.
Las rutas hello
e index
no están declaradas por lo que si se intenta acceder a http://localhost:8000 y http://localhost:8000/hello mostrará lo siguiente.
Estas rutas y su manejador correspondiente deberán declararse en el código en caso de que se necesite, y montarlas usando la macro routes
.
Métodos
Los métodos soportados por Rocket son los siguientes:
- get
- put
- post
- delete
- head
- patch
- options
Direcciones dinámicas
...
use rocket::http::RawStr;
#[get("/hello/<name>")]
fn hello(name: &RawStr) -> String {
format("¡Hola, {}!", name.as_str())
}
Una ruta puede recibir parámetros, como se observa en el código anterior, en el que la ruta hello
recibe el parámetro <name>
, que en el manejador de peticiones correspondiente, hello
, guarda en la variable name
, para luego imprimir como parte del texto que mostrará en el navegador.
&RawStr es un tipo de dato de Rocket, por lo que hay que decirle a Rust que se usará con la línea use rocket::http::RawStr
.
Al visitar /hello/Mario
en el navegador aparecerá lo siguiente.
Archivos estáticos
En la estructura de directorios de Rocket, el directorio src es donde se guardan las imágenes, archivos de JavaScript y hojas de estilo (CSS).
...
use std::path::{Path, PathBuf};
use rocket::response::NamedFile;
...
#[get("/<file..>")]
fn files(file: PathBuf) -> Option<NamedFile> {
NamedFile::open(Path::new("static/").join(file)).ok()
}
fn main() {
rocket::ignite().mount("/", routes![index, files]).launch();
}
Toda petición GET
para abrir un archivo enviada a /
será recibida en el parámetro <file..>
y manejada por la función files
.
La línea NamedFile::open(Path::new("static/").join(file)).ok()
se usa para decirle a Rust cual es el directorio donde se encuentran los archivos estáticos.
Con una nueva ruta declarada, esta debe agregarse a la macro routes
para que pueda montarse correctamente.
Plantillas
Rocket soporta Tera y Handlebars como sistemas de plantillas.
Cargo.toml
En el archivo Cargo.toml se agrega lo siguiente para decirle que se usará Handlebars. Si se usa Tera solo se reemplaza handlebars
por tera
.
...
handlebars = "1.1.0"
[dependencies.rocket_contrib]
version = "0.4"
features = ["handlebars_templates"]
src/main.rs
Una vez que se indica cuales son las dependencias necesarias para usar cualquiera de los sistemas de plantillas, se modifica el archivo main.rs en src.
...
extern crate rocket_contrib;
use rocket_contrib::templates::{template, handlebars};
#[get("/")]
fn index() -> Template {
Template::render("index")
}
...
fn main() {
rocket::ignite().mount("/", routes![index, files])
.attach(Template::fairing())
.launch();
}
En primer lugar se importa el crate rocket_contrib y todas sus macros con la línea extern crate rocket_contrib
. En seguida se indica el sistema de plantillas que se usará con la línea use rocket_contrib::templates::{template, handlebars};
.
Para importar una plantilla se usa la función render
y se especifica el tipo de dato que la función debe retornar, en este caso es Template
.
Para asegurar que el middleware (fairing, como se conoce en Rocket) de Template se adjunte a la aplicación, en la función principal se agrega la línea .attach(Template::fairing())
.
Las plantillas deberán colocarse en el directorio templates y el nombre debe corresponder con el indicado en Template::render("index")
. Del código anterior se infiere que el nombre de la plantilla es index.html.hbs
.
En este artículo he descrito de manera general como se crea una aplicación web con Rocket. Espero que la información sea útil. En un próximo artículo mostraré un ejemplo de aplicación desarrollada con este framework.
Top comments (0)