¿Cómo desplegar una aplicación Rust?

How to Deploy an Rust Application_
How to Deploy an Rust Application_

Rust ha sido el lenguaje más admirado en la encuesta de desarrolladores de StackOverflow durante más de 4 años debido a las múltiples características que ofrece a quienes lo adoptan.

Mozilla creó Rust para que fuera fiable, eficaz y fácil de usar para los desarrolladores. Rust tiene una sintaxis similar a la de lenguajes como C++ y C, cuyos desarrolladores son el principal objetivo del lenguaje.

Rust también se centra en la seguridad de la memoria y la concurrencia con modelos que evitan los escollos asociados a los que se enfrentan los desarrolladores que utilizan otros lenguajes.

Aprenderás a construir APIs en Rust para aprovechar los beneficios de este artículo. Aprenderás creando, conteniendo y desplegando una aplicación Rust en el servicio gratuito de contenedorización de Back4app.

Ventajas de utilizar Rust

El uso de Rust en tus proyectos tiene muchas ventajas. Estas son algunas de las más importantes:

Abstracciones de coste cero

Rust proporciona abstracciones de alto nivel sin imponer costes adicionales en tiempo de ejecución. Esto insinúa que las abstracciones que utilices en tu código (funciones, iteradores o genéricos) no hacen que tus programas sean más lentos.

El compilador de Rust optimiza manualmente las abstracciones del código compilado de bajo nivel. Rust tiende un puente entre el control expresivo, de bajo nivel y de grano fino sobre el rendimiento.

El enfoque Fearless Concurrency para la seguridad de memoria en programas concurrentes

Rust adopta un “enfoque intrépido” de la concurrencia caracterizado por la seguridad y la eficiencia. El modelo de concurrencia de Rust aprovecha su modelo de propiedad y la comprobación de tipos para evitar carreras de datos en tiempo de compilación.

Esta función permite escribir aplicaciones multihilo sin los inconvenientes de la concurrencia de estados compartidos, como los bloqueos y las condiciones de carrera.

Sistema tipográfico avanzado y modelo de propiedad

El sistema de tipos de Rust y sus reglas de propiedad son características únicas que ayudan a reforzar la seguridad de la memoria.

El modelo de propiedad utiliza el verificador de préstamos para garantizar que cada dato tiene un único propietario y gestiona su ciclo de vida para evitar problemas como punteros colgantes y fugas de memoria.

Compatibilidad e integración entre plataformas

Rust es una gran elección si quieres crear aplicaciones multiplataforma. Puedes escribir código una vez y compilarlo en múltiples plataformas sin cambios significativos en la base de código existente.

Rust se integra bien con otros lenguajes de programación, especialmente con C, lo que lo hace adecuado para tareas de ensamblaje web y sistemas embebidos.

Limitaciones del uso de Rust

Es probable que te encuentres con algunos contratiempos a la hora de crear aplicaciones de producción con Rust.

Algunas de ellas pueden ser la pronunciada curva de aprendizaje de Rust, el mayor tiempo de compilación debido a las comprobaciones de memoria y de otro tipo, y su nuevo y pequeño ecosistema.

Hay algunos inconvenientes que puede encontrar al construir productos de grado de producción con Rust. He aquí algunos de ellos:

La curva de aprendizaje de la programación en Rust es pronunciada

En comparación con otros lenguajes populares (Go, Python, JavaScript, etc.), se necesita mucho tiempo para dominar Rust y crear aplicaciones de producción con este lenguaje.

Esto no debería hacerte rehuir el uso de Rust. Al dominar Rust, serás realmente productivo construyendo y desplegando aplicaciones, y obtendrás todos los beneficios de usar Rust.

Los programas Rust tardan mucho en compilarse

Las comprobaciones de memoria y concurrencia en tiempo de compilación, junto con otros factores, dan lugar a largos tiempos de compilación para los programas Rust.

Dependiendo del tamaño de la aplicación, los largos tiempos de compilación pueden provocar cuellos de botella en las fases de desarrollo o producción.

Rust tiene un ecosistema de bibliotecas más pequeño

Rust es relativamente nuevo en comparación con muchos otros lenguajes populares, y existe un ecosistema limitado de bibliotecas que puedes utilizar.

Muchas bibliotecas (crates) aún están en producción, y puedes consultar sitios web como AreWeWebYet para obtener una visión general de las crates listas para producción que puedes utilizar para crear aplicaciones web en Rust.

Opciones de implantación de Rust

Rust ya está ganando una amplia adopción, por lo que hay muchas opciones de despliegue que puede elegir para sus aplicaciones.

La mayoría de las opciones de despliegue de Rust son plataformas basadas en IaaS o CaaS. Puedes elegir una en función de las especificaciones de tu proyecto.

Infraestructura como servicio (IaaS) como AWS

Los proveedores de infraestructura como servicio (IaaS) le proporcionan la infraestructura para desplegar y gestionar sus aplicaciones en máquinas virtuales en la nube.

Puede utilizar los servicios que ofrecen las plataformas IaaS para desplegar sus aplicaciones Rust en máquinas virtuales que ejecuten sistemas operativos como Linux, Windows, macOS y otros sistemas operativos compatibles con Rust.

He aquí una lista de las plataformas IaaS más populares:

  • Amazon Web Services
  • Digital Ocean
  • Google Cloud
  • Linode
  • Microsoft Azure

Containerización como servicio como Back4app Containers

Los proveedores de servicios de contenedorización (CaaS) le ayudan a facilitar el despliegue de su aplicación con tecnologías de contenedorización.

Para desplegar su aplicación en plataformas compatibles con la contenedorización, deberá agrupar su aplicación y todas sus dependencias en un contenedor aislado.

Los contenedores están aislados y son portátiles, pero tendrás que trabajar dentro de los límites de las características del proveedor de CaaS.

Algunos proveedores de IaaS ofrecen funciones de CaaS. Asimismo, hay plataformas que solo proporcionan funcionalidades CaaS flexibles de forma aislada.

He aquí una lista de algunas plataformas CaaS:

  • Oracle Container Service
  • Back4app
  • Mirantix
  • Docker Enterprise

El proceso de implantación de aplicaciones de Rust

En esta sección, aprenderás cómo puedes desplegar tu aplicación Rust en la plataforma CaaS de Back4app.

¿Qué es Back4app?

Back4app es una plataforma en la nube que puede aprovechar para crear y desplegar todo tipo de servicios backend para sus aplicaciones móviles, web y de otros tipos.

Back4app proporciona un agente de IA que puedes utilizar para agilizar el despliegue de tu aplicación en la plataforma. Puedes utilizarlo para gestionar tus repositorios de GitHub, desplegar código en la nube fácilmente y gestionar tus aplicaciones en ejecución.

En los servidores backend de Back4app, se pueden desplegar y ejecutar contenedores personalizados a través de la funcionalidad CaaS.

Utilizando sus imágenes contenedoras, puede ampliar la lógica de su aplicación sin preocuparse de mantener la arquitectura de su servidor.

una captura de pantalla del agente Back4app AI

Construcción e implantación

Debes tener Rust instalado en tu ordenador para seguir este tutorial. Puedes visitar la página de instalaciones de Rust para conocer las diferentes opciones de instalación disponibles.

Una vez que hayas instalado Rust, crea una sesión de terminal y ejecuta este comando para inicializar un nuevo proyecto Rust

mkdir back4app-rust-deployment && cd back4app-rust-deployment && cargo init

Cuando ejecutes el comando, deberías ver un archivo cargo. toml en el nuevo directorio que acabas de crear. Utilizarás el cargo. toml para gestionar las dependencias.

A continuación, añada estas directivas a la sección [dependencies] de su archivo Cargo.toml para instalar estas dependencias cuando compile su aplicación.

[dependencies]
actix-web = "4.0"
serde = { version = "1.0", features = ["derive"] }
serde_derive = { version = "1.0" }
serde_json = "1.0"
lazy_static = "1.4"

La crate actix-web proporciona enrutamiento y otras funciones relacionadas con HTTP, las crates serde, serde_derive y serde_json proporcionan funciones para las diferentes operaciones JSON y la crate lazy_static proporciona el almacenamiento de datos en memoria para la API en tiempo de ejecución.

Añada estas importaciones al principio de su archivo [main.rs](<http://main.rs>):

use serde::{Serialize, Deserialize};
use actix_web::{web, App, HttpServer, HttpResponse, Error};
use std::sync::Mutex;
extern crate lazy_static;
use lazy_static::lazy_static;

Puede utilizar una estructura para definir la estructura de datos de su API en función de los campos que necesite. A continuación se muestra una estructura que representa a una persona con un ID, un nombre de usuario y un correo electrónico.

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Person {
    pub id: i32,
    pub username: String,
    pub email: String,
}

Las #[derive(Serialize, Deserialize, Debug, Clone)] son implementaciones de la crate serde_derive para la estructura Persona para acceder y usar sus funciones.

A continuación se muestra cómo puede utilizar la crate lazy_static para configurar un almacén de datos en memoria para su API basado en el tipo struct Person:

lazy_static! {
    static ref DATA_STORE: Mutex<Vec<Person>> = Mutex::new(Vec::new());
}

Has creado un almacenamiento compartido inicializado perezosamente y a prueba de hilos para la estructura Personas. Lo utilizarás en tus funciones manejadoras para almacenar y recuperar datos.

La función POST Handler

La función POST request handler acepta una representación JSON de la estructura Persona como entrada. A continuación, devolverá una respuesta HTTP y un error al cliente bajo petición.

Añade este bloque de código a tu archivo [main.rs]( ) para implementar la funcionalidad del manejador de peticiones POST.

async fn create_person(new_person: web::Json<Person>) -> Result<HttpResponse, Error> {
    let mut data_store = DATA_STORE.lock().unwrap();
    let new_id = data_store.len() as i32 + 1;
    let mut person = new_person.into_inner();
    person.id = new_id;
    data_store.push(person.clone());

    Ok(HttpResponse::Ok().json(person))
}

La función create_person es una función asíncrona que accede al almacén de datos compartido, genera un nuevo ID para la estructura Persona, convierte la representación JSON Persona en una estructura y la introduce en el almacén de datos.

Tras una solicitud correcta, la función proporciona al cliente los datos introducidos en la base de datos junto con un código de estado 200.

La función GET Handler

Aquí una función GET handler demuestra la lectura de todos los datos en el almacén de datos y devolverlos al cliente como JSON.

Añade este bloque de código a tu proyecto para implementar una función GET handler

async fn get_people() -> Result<HttpResponse, Error> {
    let data_store = DATA_STORE.lock().unwrap();
    let people: Vec<Person> = data_store.clone();

    Ok(HttpResponse::Ok().json(people))
}

La función get_people es una función asíncrona que accede al almacén de datos y escribe el contenido al cliente como respuesta.

Si la solicitud tiene éxito, la función responde con el código de estado 200 al cliente con todos los datos del almacén de datos.

La función PUT Handler

Su función manejadora de peticiones PUT debe actualizar una entrada en el almacén de datos basándose en un campo del objeto.

A continuación le mostramos cómo puede implementar una función manejadora PUT para su API:

async fn update_person(
    id: web::Path<i32>,
    person_update: web::Json<Person>,
) -> Result<HttpResponse, Error> {
    let mut data_store = DATA_STORE.lock().unwrap();

    if let Some(person) = data_store.iter_mut().find(|p| p.id == *id) {
        *person = person_update.into_inner();
        Ok(HttpResponse::Ok().json("Person updated successfully"))
    } else {
        Ok(HttpResponse::NotFound().json("Person not found"))
    }
}

La función update_person toma el ID y la nueva entrada de la solicitud. A continuación, recorre el almacén de datos y sustituye la entrada por la nueva, si existe.

Función DELETE Handler

La función de solicitud DELETE tomará un argumento; el campo ID de la solicitud realizada. Al ejecutarse la función, eliminará la entrada con el ID del almacén de datos.

Añade esta implementación de la función DELETE a tu programa.

// DELETE
pub async fn delete_person(id: web::Path<i32>) -> Result<HttpResponse, Error> {
    let mut data_store = DATA_STORE.lock().unwrap();

    if let Some(index) = data_store.iter().position(|p| p.id == *id) {
        data_store.remove(index);
        Ok(HttpResponse::Ok().json("Deleted successfully"))
    } else {
        Ok(HttpResponse::NotFound().json("Person not found"))
    }
}

La función delete_person elimina la entrada con el ID especificado del almacén de datos. Dependiendo del estado de la operación, la función devuelve al cliente una cadena y un código de estado.

Asignación de funciones de gestión a rutas

Después de definir los puntos finales, tendrá que asignar rutas a las funciones de control para acceder a la funcionalidad de las funciones de control.

A continuación se explica cómo asignar rutas a funciones de controlador:

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .route("/person", web::post().to(create_person))
            .route("/people", web::get().to(get_people))
            .route("/person/{id}", web::put().to(update_person))
            .route("/person/{id}", web::delete().to(delete_person))
    })
        .bind("0.0.0.0:8000")?
        .run()
        .await
}

La función principal es una función asíncrona que configura el servidor después de asignar las rutas a las funciones manejadoras.

La función HttpServer::new instancia un servidor HTTP, la función App::new() crea una nueva instancia de aplicación, y la función route asigna rutas a la función handler.

La función bind especifica la dirección de la nueva aplicación, y la función run ejecuta la aplicación.

Contenedorización de aplicaciones Rust con Docker

Docker es la tecnología de contenedorización más popular del mercado. Puedes contenerizar tus aplicaciones Rust con Docker para portabilidad y desplegarlas en Back4app con unos pocos clics.

Ejecute este comando para crear un nuevo Dockerfile en su proyecto:

touch Dockerfile

Abra el Dockerfile y añada estas instrucciones de compilación al Dockerfile:

# Use Rust Nightly as the base image
FROM rustlang/rust:nightly

# Set the working directory inside the container
WORKDIR /usr/src/myapp

# Copy the current directory contents into the container
COPY . .

# Build the application
RUN cargo build --release

# Expose port 8000
EXPOSE 8000

# Define the command to run the application
CMD ["./target/release/back4app-rust-deployment"]

Estas instrucciones especifican la imagen base y las instrucciones de compilación para contenerizar su aplicación Rust con Docker.

He aquí un desglose del contenido del Dockerfile:

  1. La directiva FROM rustlang/rust:nightly especifica la imagen base para el Dockerfile. Docker extrae esta imagen del repositorio y construye tus programas sobre ella.
  2. La directiva WORKDIR /usr/src/myapp establece el directorio de trabajo para tu aplicación dentro del contenedor.
  3. La directiva COPY . . copia todo el contenido de su directorio de trabajo en el directorio de trabajo actual del contenedor.
  4. La directiva RUN cargo build --release ejecuta el comando para construir tu aplicación en el contenedor.
  5. La directiva EXPOSE 8000 expone el puerto 8000 del contenedor para peticiones entrantes.
  6. El CMD ["./target/release/back4app-rust-deployment"] ejecuta el programa (el ejecutable de la operación de compilación).

Una vez que hayas escrito el Dockerfile, puedes proceder a desplegar el contenedor en el servicio de contenedores de Back4app.

Desplegando un Contenedor en Back4app

Necesitas crear una cuenta en Back4app para desplegar contenedores.

Estos son los pasos para crear una cuenta Back4app.

  1. Visite el sitio web de Back4app
  2. Haga clic en el botón Inscribirse situado en la esquina superior derecha de la página.
  3. Rellene el formulario de inscripción y envíelo para crear la cuenta.

Ahora que has creado con éxito una cuenta Back4app, inicia sesión y haz clic en el botón NUEVA APP situado en la esquina superior derecha de la página de destino.

Se te presentarán opciones para elegir cómo quieres construir tu aplicación. Elija la opción Contenedor como servicio.

Seleccionar un servicio back4app

Ahora, conecta tu cuenta de Github a tu cuenta de Back4app y configura el acceso a los repositorios de tu cuenta o a un proyecto específico.

Configura tu cuenta de GitHub para otorgar acceso a Back4app para importar un repositorio

Elija la aplicación que desea desplegar (la de este tutorial) y haga clic en Seleccionar.

seleccionar y configurar los repos accesibles

Al hacer clic en Seleccionar, el botón te llevará a una página en la que podrás rellenar información sobre tu aplicación, incluido el nombre de la rama, el directorio raíz y las variables de entorno.

El proceso de despliegue se inicia automáticamente,

Implementación con el agente de IA de Back4app

Para potenciar tu flujo de trabajo de desarrollo, también puedes desplegar tu aplicación utilizando el agente Back4app AI, como puedes ver en la siguiente imagen:

Solicitar al agente de IA una orden de despliegue

Sigue este enlace para instalar la app contenedora Back4app en tu cuenta de GitHub, y sigue los pasos de la imagen superior para configurarla.

Una vez completada la configuración de la aplicación, puede proceder a desplegarla con el agente de IA.

El despliegue de su contenedor se ha inicializado con un mensaje

Siga el enlace proporcionado para supervisar el progreso de despliegue de su aplicación.

Una captura de pantalla de su panel de control de Contenedores para supervisar el despliegue

Conclusión

Has aprendido a construir y desplegar una aplicación Rust contenida en Docker en Back4app.

Desplegar sus aplicaciones en Back4app es una excelente manera de simplificar la gestión de la infraestructura de backend.

Back4App proporciona potentes herramientas para gestionar sus datos, escalar su aplicación y supervisar su rendimiento.

Es una opción excelente para los desarrolladores que buscan crear grandes aplicaciones en lugar de gestionar servidores.


Leave a reply

Your email address will not be published.