49 - Diseñando un microservicio en Rust - planificación y arquitectura

49 - Diseñando un microservicio en Rust - planificación y arquitectura

¡Bienvenidos de nuevo a Rustaceo.es! En este artículo, exploraremos cómo diseñar y estructurar un microservicio en Rust, abordando los principios clave de arquitectura, modularidad y eficiencia en el desarrollo de servicios distribuidos.


🚀 Principios de diseño para microservicios en Rust #

Un microservicio bien diseñado debe cumplir con las siguientes características: ✔ Autonomía: Independencia en su lógica y almacenamiento de datos. ✔ Escalabilidad: Capacidad de crecer horizontalmente según la demanda. ✔ Resiliencia: Tolerancia a fallos sin afectar a otros servicios. ✔ Comunicaciones Eficientes: API bien definidas para la interacción con otros servicios. ✔ Seguridad: Control de acceso y protección contra amenazas.


🏗 Arquitectura de un microservicio en Rust #

Un microservicio típico en Rust consta de los siguientes componentes:

📌 1️⃣ Interfaz http con actix-web #

  • Manejo de rutas y respuestas.
  • Middleware para seguridad y logging.

📌 2️⃣ Persistencia con sqlx y postgresql #

  • Conexión segura a la base de datos.
  • Consultas eficientes y transacciones.

📌 3️⃣ Comunicación entre microservicios #

  • Consumo de APIs con reqwest.
  • Integración con sistemas de mensajería como Kafka o NATS.

📌 4️⃣ Seguridad y autenticación #

  • Uso de JWT para control de acceso.
  • Middleware para validación de usuarios.

📌 5️⃣ Observabilidad y monitoreo #

  • Logging estructurado con tracing.
  • Exportación de métricas con Prometheus.

🌐 Definiendo la interfaz http #

Comenzamos definiendo la estructura base del microservicio con Actix-Web:

use actix_web::{web, App, HttpResponse, HttpServer, Responder};

async fn status() -> impl Responder {
    HttpResponse::Ok().json({ "status": "Microservicio en ejecución" })
}

#[Actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .route("/status", web::get().to(status))
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await
}

Definimos un endpoint /status para verificar la disponibilidad del servicio.Actix-Web permite manejar múltiples rutas y middleware de manera eficiente.


🛠 Configuración de persistencia con sqlx y postgresql #

Para manejar almacenamiento de datos, utilizamos SQLx con PostgreSQL:

use sqlx::PgPool;
use actix_web::{web, App, HttpResponse, HttpServer, Responder};

async fn obtener_datos(pool: web::Data<PgPool>) -> impl Responder {
    let datos = sqlx::query!("SELECT * FROM datos")
        .fetch_all(pool.get_ref())
        .await;
    
    match datos {
        Ok(datos) => HttpResponse::Ok().json(datos),
        Err(_) => HttpResponse::InternalServerError().finish(),
    }
}

Gestión segura de la base de datos con SQLx.Evita inyecciones SQL utilizando consultas parametrizadas.


📡 Comunicación entre microservicios #

Los microservicios necesitan interactuar con otros sistemas. Usamos reqwest para consumir APIs externas:

use reqwest;

#[Tokio::main]
async fn main() {
    let respuesta = reqwest::get("http://127.0.0.1:8080/status")
        .await.unwrap()
        .text()
        .await.unwrap();
    
    println!("Respuesta del servicio: {}", respuesta);
}

Uso de reqwest::get() para realizar peticiones HTTP a otros servicios.Manejo de respuestas asíncronas sin bloquear el sistema.


🔐 Seguridad y autenticación #

Implementamos autenticación con JWT para asegurar las comunicaciones:

use jsonwebtoken::{decode, encode, Header, Validation, EncodingKey, DecodingKey};

#[Derive(serde::serialize, serde::deserialize)]
struct Claims {
    sub: String,
    exp: usize,
}

Protección contra accesos no autorizados.Validación de tokens para controlar el acceso a rutas protegidas.


📊 Observabilidad y monitoreo #

Para asegurar la confiabilidad del microservicio, usamos tracing para logging estructurado y exportamos métricas a Prometheus.

📌 Ejemplo de Logging con tracing:

use tracing::{info, error};

fn main() {
    info!("Microservicio iniciado");
    error!("Error crítico detectado");
}

Logs estructurados para debugging y monitoreo.Integración con sistemas de observabilidad.


🏆 Conclusión #

Hemos diseñado un microservicio en Rust basado en principios sólidos de arquitectura.

🎯 Resumen de lo aprendido: ✔ Definición de la interfaz HTTP con Actix-Web. ✔ Gestión de datos con PostgreSQL y SQLx. ✔ Comunicación entre microservicios con reqwest. ✔ Seguridad con JWT para autenticación. ✔ Monitoreo con tracing y Prometheus.

🔮 Próximo paso: Implementar despliegue con Docker y Kubernetes.

¡Nos vemos en la siguiente entrega, Rustaceos!