Construye una API REST segura con Rust y Actix Web

Construye una API REST segura con Rust y Actix Web

Meta

  • Meta title sugerido: Tutorial Rust Actix Web: Crea una API REST segura con SQLx, JWT y Docker
  • Meta description sugerida: Guía paso a paso para construir una API REST en Rust con Actix Web. Incluye SQLx PostgreSQL, autenticación JWT, validación, logging, rate limiting, OpenAPI, pruebas y Docker Compose.
  • URL slug sugerido: tutorial-rust-actix-web-api-rest-segura-sqlx-jwt-docker

Tutorial Rust Actix Web: Crea una API REST segura con SQLx, JWT y Docker

En esta guía práctica construirás una API REST en Rust con Actix Web, conectada a PostgreSQL mediante SQLx, con autenticación JWT, validación, logging con tracing, rate limiting, CORS y documentación OpenAPI. Está diseñada para backend developers principiantes e intermedios con nociones básicas de HTTP y SQL. Al final podrás ejecutar todo con Docker Compose y tendrás bases para desplegar en producción.

Indice general (secciones numeradas):

  1. Introducción y objetivos
  2. Requisitos previos
  3. Crear el proyecto y organizar la estructura
  4. Configuración por entornos (config/dotenv)
  5. PostgreSQL con SQLx: pool, timeouts, retries, migraciones y seeding
  6. Modelo de dominio y DTOs con validación
  7. Manejo global de errores
  8. Logging y trazas con tracing
  9. Seguridad: CORS, cabeceras y rate limiting
  10. Autenticación y autorización con JWT y Argon2
  11. Rutas y CRUD REST (tareas) con paginación/filtrado/ordenación
  12. Documentación OpenAPI (utoipa + swagger-ui)
  13. Pruebas unitarias e integración
  14. Rendimiento y concurrencia
  15. Contenedorización con Docker y orquestación local con Docker Compose
  16. Preparación para despliegue y observabilidad
  17. Resolución de problemas comunes (FAQ técnica)
  18. Conclusión y próximos pasos

1. Introducción y objetivos

Construiremos una API REST Rust con Actix Web centrada en buenas prácticas de seguridad y rendimiento. Expondremos un recurso de ejemplo: tareas (Task). Implementaremos CRUD, autenticación JWT, validación y documentación. Usaremos SQLx para consultas tipadas en PostgreSQL y Docker para ejecutar todo localmente.

Checklist

  • Entenderás la arquitectura del proyecto (src/, routes/, handlers/, models/, db/, auth/)
  • Aprenderás a configurar, integrar y probar SQLx con migraciones
  • Añadirás logging estructurado, CORS y rate limiting
  • Implementarás autenticación JWT segura
  • Documentarás la API con OpenAPI y swagger-ui

2. Requisitos previos

  • Rust y herramientas
  • rustup, cargo, rustc
  • Instala: curl —proto ‘=https’ —tlsv1.2 -sSf https://sh.rustup.rs | sh
  • PostgreSQL (local o en Docker)
  • SQLx CLI
  • Docker y Docker Compose
  • Cliente HTTP: Postman, Insomnia, HTTPie o curl

Comandos útiles:

Explicación: Necesitamos Rust y cargo para compilar. SQLx CLI gestiona migraciones. Docker/Compose nos permite levantar API + PostgreSQL localmente.

Checklist

  • Rust y Cargo instalados
  • SQLx CLI operativo
  • Docker y Compose disponibles
  • Cliente HTTP listo

3. Crear el proyecto y organizar la estructura

Explicación: Creamos un binario llamado actix-tasks-api.

Estructura propuesta:

Explicación: Mantenemos módulos claros: configuración, DB, modelos, autenticación, rutas/handlers y documentación.

Añade dependencias en Cargo.toml:

Explicación: Estas crates cubren el stack: Actix Web, CORS, rate limiting, SQLx PostgreSQL, validación, JWT/Argon2, logging/tracing, OpenAPI y métricas.

Checklist

  • Proyecto creado
  • Estructura y Cargo.toml listos

4. Configuración por entornos (config/dotenv)

Crea config/default.toml:

Crea .env (no lo subas a git):

Carga de configuración en src/config.rs:

Explicación: Combinamos archivos TOML y variables de entorno. DATABASEURL y JWTSECRET van en .env.

Checklist

  • Variables de entorno definidas
  • Config loader implementado

5. PostgreSQL con SQLx: pool, timeouts, retries, migraciones y seeding

Conexión y pool en src/db.rs:

Explicación: Creamos un pool con límites y reintentos exponenciales ante fallos temporales.

Migraciones:

Archivo migrations/0001createtables.sql:

Explicación: Creamos tablas users y tasks con índices.

Ejecutar migraciones:

Seeding opcional: migrations/0002_seed.sql

Explicación: Puedes sembrar un usuario de prueba. Más abajo veremos cómo generar el hash.

Checklist

  • Pool configurado con timeouts y retries
  • Migraciones creadas y aplicadas
  • Datos de prueba opcionales insertados

6. Modelo de dominio y DTOs con validación

src/models.rs:

Explicación: Definimos el modelo Task y DTOs con validator para asegurar entradas correctas. ToSchema expone esquemas para OpenAPI.

Checklist

  • DTOs con validación listos
  • Modelo de dominio mapeado a SQLx

7. Manejo global de errores

src/errors.rs:

Explicación: Unificamos errores en AppError y los convertimos en respuestas HTTP con ResponseError.

Checklist

  • Tipos de error centralizados
  • Respuestas JSON coherentes

8. Logging y trazas con tracing

Inicializa tracing en main:

Explicación: Configuramos logging estructurado en JSON, útil en producción.

Checklist

  • Logging estructurado activo

9. Seguridad: CORS, cabeceras y rate limiting

Middleware en main (veremos main completo en la sección 11):

Explicación: CORS configurable y rate limiting básico por IP. También añadiremos cabeceras de seguridad con DefaultHeaders.

Checklist

  • CORS ajustado
  • Rate limiting configurado
  • Cabeceras seguras planificadas

10. Autenticación y autorización con JWT y Argon2

src/auth.rs:

Explicación: Hasheamos contraseñas con Argon2 y firmamos/validamos JWT HS256. AuthUser extrae el id de usuario desde Authorization: Bearer.

Checklist

  • Hash y verificación implementados
  • JWT firmado/validado
  • Extractor AuthUser listo

11. Rutas y CRUD REST (tareas) con paginación/filtrado/ordenación

src/handlers/auth.rs:

Explicación: Registro y login. Devolvemos id en register y token JWT en login.

src/handlers/tasks.rs:

Explicación: Implementamos CRUD con paginación, filtros por status y sort por campo con – para descendente. Restringimos por owner_id del token.

src/routes.rs:

Explicación: Registramos endpoints.

src/main.rs (ensamblado):

Explicación: Ensamblamos el servidor: migraciones al inicio, middlewares de trazas, CORS, cabeceras y rate limiting; exponemos /health y /metrics; servimos Swagger en /docs.

Probar endpoints con HTTPie:

Checklist

  • Endpoints CRUD operativos
  • Seguridad por usuario aplicada
  • Healthcheck y métricas expuestos

12. Documentación OpenAPI (utoipa + swagger-ui)

src/docs.rs:

Explicación: Generamos OpenAPI y añadimos esquema de seguridad Bearer JWT. Swagger UI servirá en /docs.

Checklist

  • OpenAPI generado
  • Swagger UI accesible en /docs

13. Pruebas unitarias e integración

Unit test simple de validación:

Explicación: Probamos reglas de validator.

Integración con servidor en memoria:

Explicación: Prueba básica. Para pruebas de DB, usa Testcontainers o un Postgres en Docker Compose en CI antes de cargo test.

Testcontainers (opcional, solo referencia):

Checklist

  • Unit tests agregados
  • Integración mínima validada

14. Rendimiento y concurrencia

Buenas prácticas:

  • Configura tamaño del pool SQLx acorde a CPUs y carga (p.ej., 10-20)
  • Usa timeouts estrictos para evitar bloqueos
  • Actix Web: ajusta workers (por defecto = núcleos) y backlog
  • Respuestas JSON ligeras y paginación obligatoria
  • Evita N+1 consultas; usa índices adecuados (ya añadimos en status/owner)
  • Aplica backpressure: no hagas bloqueantes en request handlers

Checklist

  • Pool y workers ajustados
  • Consultas e índices revisados

15. Contenedorización con Docker y Docker Compose

Dockerfile multi-stage:

Explicación: Build en imagen Rust y runtime mínima. Incluye ca-certificates para TLS.

docker-compose.yml:

Explicación: Orquestamos API + Postgres. La API espera a que la DB esté saludable.

Checklist

  • Dockerfile compilando
  • Compose levantando stack local

16. Preparación para despliegue y observabilidad

Recomendaciones:

  • Variables de entorno seguras (JWT_SECRET desde el entorno/secret manager)
  • Healthcheck /health y métricas /metrics para Prometheus
  • Migraciones en startup (ya implementadas)
  • Logs JSON y niveles adecuados
  • CORS restrictivo en producción (dominios específicos)
  • Instrumentar endpoints críticos con tracing spans

Checklist

  • Salud y métricas habilitadas
  • Secrets gestionados correctamente
  • CORS endurecido

17. Resolución de problemas comunes (FAQ técnica)

  • Error: sqlx::Error(Database) connection refused
  • Verifica DATABASE_URL, que Postgres esté activo y puertos expuestos. En Docker, usa el nombre de servicio (db) en lugar de localhost.
  • Migraciones fallan por falta de extensión genrandomuuid
  • Habilita la extensión: CREATE EXTENSION IF NOT EXISTS pgcrypto; añádelo en la primera migración.
  • Token JWT inválido/expirado
  • Confirma que usas el mismo JWT_SECRET para firmar y validar; revisa exp/iss.
  • CORS bloquea peticiones desde el navegador
  • Ajusta allowed_origins en config para incluir el dominio frontend.
  • Rate limiting demasiado agresivo
  • Incrementa per_second/burst en configuración o excluye rutas internas.
  • Hash de contraseña incompatible
  • Usa Argon2id con parámetros por defecto; no guardes contraseñas en claro.
  • Errores 500 opacos
  • Activa RUST_LOG=debug y revisa logs/tracing; implementa AppError con más contexto.
  • Pruebas con DB inestables en CI
  • Levanta Postgres con docker compose en job antes de cargo test; aplica migraciones.

18. Conclusión y próximos pasos

Has construido una API REST Rust segura con Actix Web, SQLx PostgreSQL, autenticación JWT, validación, logging, rate limiting y documentación OpenAPI. Contenedorizaste con Docker y orquestaste con Docker Compose, y preparaste salud, métricas y migraciones para despliegue.

Próximos pasos y llamada a la acción:

  • Extiende el modelo (etiquetas de tareas, comentarios) y añade tests de integración completos
  • Implementa refresh tokens y roles/autorización granular
  • Añade caché (Redis) para listas y rate limiting distribuido
  • Despliega en tu cloud favorito con una base de datos gestionada y Prometheus + Grafana para observabilidad

Si este tutorial te ayudó, comparte la guía y lánzate a crear tu próxima API REST Rust con Actix Web en producción.