Microservicios en Rust: arquitectura, práctica y ejemplos de código

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: ¿Por qué Rust para microservicios?



La arquitectura de microservicios se ha convertido en el estándar para los sistemas distribuidos modernos. Sin embargo, la elección del lenguaje de programación para implementar microservicios es una decisión crítica. Rust ofrece una combinación única del rendimiento de C/C++ y la seguridad de memoria, lo que lo convierte en un candidato ideal para servicios de alta carga.



En este artículo, analizaremos cómo construir un microservicio en Rust utilizando los frameworks populares Actix-web y Tokio. Aprenderá sobre principios arquitectónicos, procesamiento asíncrono de solicitudes y obtendrá ejemplos de código funcionales.



Arquitectura de un microservicio en Rust



Principios básicos



Un microservicio en Rust generalmente se construye alrededor de los siguientes componentes:

  • Servidor HTTP — procesamiento de solicitudes entrantes (Actix-web, Warp, Axum).
  • Runtime asíncrono — gestión de concurrencia (Tokio, async-std).
  • Lógica de negocio — módulos aislados con límites claros.
  • Almacenamiento de datos — interacción con la base de datos a través de SQLx o Diesel.
  • Comunicación entre servicios — HTTP/gRPC o colas de mensajes (RabbitMQ, Kafka).


Estructura del proyecto



Estructura recomendada para un microservicio en Rust:



my_microservice/├── Cargo.toml├── src/│   ├── main.rs          # Punto de entrada, inicio del servidor│   ├── routes/          # Definición de rutas│   ├── handlers/        # Manejadores de solicitudes│   ├── models/          # Estructuras de datos (DTO, entidades)│   ├── services/        # Lógica de negocio│   ├── repositories/    # Capa de acceso a datos│   └── config/          # Configuración (env, archivos)└── tests/               # Pruebas de integración


Ejemplo práctico: servicio de acortamiento de enlaces



Consideremos la creación de un microservicio simple para acortar URLs. Recibirá enlaces largos y devolverá identificadores cortos.



Paso 1: Configuración del proyecto



Cree un nuevo proyecto Cargo y agregue las dependencias en Cargo.toml:



[package]name = "url-shortener"version = "0.1.0"edition = "2021"

[dependencies]actix-web = "4"actix-rt = "2"serde = { version = "1", features = ["derive"] }serde_json = "1"tokio = { version = "1", features = ["full"] }redis = { version = "0.23", features = ["tokio-comp"] }uuid = { version = "1", features = ["v4"] }dotenv = "0.15"env_logger = "0.10"log = "0.4"


Paso 2: Modelos de datos



Definamos las estructuras de solicitud y respuesta:



// models/mod.rsuse serde::{Deserialize, Serialize};

#[derive(Debug, Deserialize)]pub struct CreateUrlRequest { pub url: String,}

#[derive(Debug, Serialize)]pub struct CreateUrlResponse { pub short_code: String, pub original_url: String,}

#[derive(Debug, Serialize)]pub struct ErrorResponse { pub error: String,}


Paso 3: Capa de servicio



Implementemos la lógica de negocio utilizando Redis para el almacenamiento:



// services/url_service.rsuse redis::AsyncCommands;use uuid::Uuid;

pub struct UrlService { redis_client: redis::Client,}

impl UrlService { pub fn new(redis_client: redis::Client) -> Self { Self { redis_client } }

pub async fn create_short_url(&self, original_url: &str) -> Result<String, String> { let short_code = Uuid::new_v4().to_string()[..8].to_string(); let mut conn = self.redis_client .get_multiplexed_async_connection() .await .map_err(|e| format!("Redis connection error: {}", e))?;

// Guardamos en Redis: clave — short_code, valor — original_url conn.set_ex(&short_code, original_url, 86400) // TTL 24 horas .await .map_err(|e| format!("Redis

Blogs

Book Recommendations