Introducción: ¿Por qué Rust para REST API?
Rust es un lenguaje de programación de sistemas moderno que combina el rendimiento de C++ con la seguridad de memoria garantizada en tiempo de compilación. En los últimos años, Rust se ha utilizado activamente para crear servicios web y microservicios de alta carga. En este artículo, mostraremos cómo escribir una API REST completa en Rust en 30 minutos utilizando el framework Actix-web y la biblioteca Serde.
¿Por qué elegir Rust para tu API?
- Rendimiento: Rust funciona al nivel de C/C++, lo cual es crítico para sistemas de alta carga.
- Seguridad: El sistema de ownership y borrowing elimina clases enteras de errores relacionados con la memoria.
- Asincronía: El soporte incorporado para async/await permite manejar eficientemente miles de conexiones.
- Ecosistema: Cargo (gestor de paquetes) y crates.io hacen que la gestión de dependencias sea simple y conveniente.
Crearemos una API simple para gestionar una lista de tareas (Todo list) que admitirá operaciones CRUD. Aprenderás a configurar rutas, manejar JSON y trabajar con el estado de la aplicación.
Paso 1: Configuración del proyecto e instalación de dependencias
Primero, crearemos un nuevo proyecto en Rust usando Cargo. Abre la terminal y ejecuta:
cargo new rust_todo_apicd rust_todo_apiAhora editemos el archivo Cargo.toml, agregando las dependencias necesarias:
[package]name = "rust_todo_api"version = "0.1.0"edition = "2021"
[dependencies]actix-web = "4"serde = { version = "1.0", features = ["derive"] }serde_json = "1.0"tokio = { version = "1", features = ["full"] }uuid = { version = "1", features = ["v4"] }Analicemos para qué sirve cada biblioteca:
- actix-web — framework web asíncrono de alto rendimiento.
- serde — biblioteca para serialización y deserialización de datos (JSON).
- serde_json — soporte para el formato JSON en serde.
- tokio — runtime asíncrono para Rust (actix-web lo usa por defecto).
- uuid — generación de identificadores únicos para nuestras tareas.
Después de agregar las dependencias, ejecuta cargo build para descargar y compilar todos los paquetes. Esto puede tomar unos minutos en la primera ejecución.
Paso 2: Creación del modelo de datos y estructura de la aplicación
Creemos el archivo src/main.rs y definamos el modelo de nuestra tarea. Usaremos la estructura TodoItem con los campos id, title y completed:
use actix_web::{web, App, HttpServer, HttpResponse, middleware};use serde::{Deserialize, Serialize};use std::sync::Mutex;use uuid::Uuid;
#[derive(Debug, Serialize, Deserialize, Clone)]struct TodoItem { id: String, title: String, completed: bool,}
#[derive(Debug, Deserialize)]struct CreateTodoRequest { title: String,}
#[derive(Debug, Deserialize)]struct UpdateTodoRequest { title: Option<String>, completed: Option<bool>,}
struct AppState { todos: Mutex<Vec<TodoItem>>,}Presta atención a los detalles importantes:
SerializeyDeserialize— traits de serde que generan automáticamente código para trabajar con JSON.Mutex— se utiliza para el acceso seguro al estado compartido desde múltiples hilos.Uuid— genera identificadores únicos para cada tarea.
Ahora agreguemos la función main que iniciará el servidor e inicializará el estado:
#[actix_web::main]async fn main() -> std::io::R