Cómo escribir una API REST en Rust en 30 minutos: para principiantes

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 API REST?

Rust es un lenguaje de programación de sistemas moderno que combina el rendimiento de C++ con la seguridad de la memoria. En los últimos años, se ha convertido en una opción popular para crear servicios web de alta carga. Si ya conoces Python y quieres probar algo nuevo, Rust será un excelente paso adelante.

En este artículo crearemos una API REST completa para gestionar una lista de tareas (Todo List) en Rust utilizando el framework Actix-web. Todo el proceso no tomará más de 30 minutos si sigues las instrucciones.



1. Preparación del entorno

Instalación de Rust

Si aún no tienes Rust instalado, ejecuta el siguiente comando en la terminal (Linux/macOS):

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Para Windows, descarga el instalador desde el sitio oficial.

Después de la instalación, verifica la versión:

rustc --version


Creación del proyecto

Crearemos un nuevo proyecto con Cargo, el gestor de paquetes de Rust:

cargo new rust_todo_apicd rust_todo_api


Adición de dependencias

Abre el archivo Cargo.toml y agrega las siguientes dependencias:

[dependencies]actix-web = "4"actix-rt = "2"serde = { version = "1", features = ["derive"] }serde_json = "1"tokio = { version = "1", features = ["full"] }

Guarda el archivo. Cargo descargará automáticamente todas las librerías en la primera compilación.



2. Creación del modelo de datos y almacenamiento

Antes de escribir los endpoints, definamos la estructura de datos. Usaremos un vector simple en memoria (para demostración).



Modelo de tarea

Crea el archivo src/models.rs:

use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize, Clone)]pub struct Task { pub id: u32, pub title: String, pub completed: bool,}


Almacenamiento global

En src/main.rs agregaremos el estado global. Para la seguridad en hilos, usaremos Mutex:

use std::sync::Mutex;use actix_web::{web, App, HttpServer, HttpResponse, HttpRequest, Responder};use models::Task;

mod models;

struct AppState { tasks: Mutex<Vec<Task>>, next_id: Mutex<u32>,}


3. Implementación de endpoints CRUD

Ahora escribiremos los manejadores principales. Todos recibirán el estado de la aplicación a través de web::Data.



GET /tasks — obtener todas las tareas

async fn get_tasks(data: web::Data<AppState>) -> impl Responder {    let tasks = data.tasks.lock().unwrap();    HttpResponse::Ok().json(tasks.clone())}


POST /tasks — crear una nueva tarea

async fn create_task(data: web::Data<AppState>, body: web::Json<Task>) -> impl Responder {    let mut tasks = data.tasks.lock().unwrap();    let mut next_id = data.next_id.lock().unwrap();    let new_task = Task {        id: *next_id,        title: body.title.clone(),        completed: false,    };    tasks.push(new_task.clone());    *next_id += 1;    HttpResponse::Created().json(new_task)}


GET /tasks/{id} — obtener una tarea por ID

async fn get_task(data: web::Data<AppState>, path: web::Path<u32>) -> impl Responder {    let id = path.into_inner();    let tasks = data.tasks.lock().unwrap();    match tasks.iter().find(|t| t.id == id) {        Some(task) => HttpResponse::Ok().json(task),        None => HttpResponse::NotFound().json("Task not found"),    }}


DELETE /tasks/{id} — eliminar una tarea

async fn delete_task(data: web::Data<AppState>, path: web::Path<u32>) -> impl Responder {    let id = path.into_inner();    l                

Blogs

Book Recommendations