Configuración del proyecto
Estructurar la API
Configuración del proyecto es una lección gratuita de Learn Rust Coding en CoddyKit. Esta es la lección 1 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Learn Rust Coding, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Learn Rust Coding incluye 4 lecciones en total.
Crear una API REST en Rust
En este curso creará una pequeña API REST en Rust. Usaremos el framework web Axum, basado en Tokio (entorno de ejecución asíncrono) y Tower (middleware). Es ergonómico, seguro respecto a los tipos y se usa ampliamente en producción.
Esta primera lección configura la estructura del proyecto para que, en lecciones posteriores, pueda añadir rutas, modelos, una base de datos y pruebas.
Crear el proyecto
Empiece con Cargo. Un proyecto binario le proporciona un punto de entrada src/main.rs:
cargo new rest_apicrea la carpeta.cd rest_apientra en ella.cargo runcompila y ejecuta el proyecto.
Estos son comandos de shell y de cargo, no fragmentos de Rust ejecutables.
// terminal
// cargo new rest_api
// cd rest_api
// cargo runAñadir dependencias
Una API de Axum necesita algunos crates en Cargo.toml:
axumpara el enrutamiento y los handlers.tokiopara el entorno de ejecución asíncrono.serdepara la serialización JSON.
// Cargo.toml
// [dependencies]
// axum = "0.7"
// tokio = { version = "1", features = ["full"] }
// serde = { version = "1", features = ["derive"] }
// serde_json = "1"El entorno de ejecución async
Los servidores web gestionan muchas conexiones simultáneamente, por lo que Axum es async. El atributo #[tokio::main] convierte un main async en un punto de entrada real al iniciar el entorno de ejecución de Tokio. Cada handler puede usar .await para realizar E/S no bloqueante.
// src/main.rs
use tokio;
#[tokio::main]
async fn main() {
println!("runtime started");
}Un servidor mínimo
La aplicación más pequeña de Axum crea un Router, enlaza un listener TCP y empieza a servir. Una única ruta asigna GET / a un handler que devuelve una cadena. Los handlers son simplemente funciones async que devuelven algo que implementa IntoResponse.
use axum::{routing::get, Router};
#[tokio::main]
async fn main() {
let app = Router::new().route("/", get(root));
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
.await.unwrap();
axum::serve(listener, app).await.unwrap();
}
async fn root() -> &'static str {
"Hello, API!"
}Cómo funciona el enrutamiento
Un Router asigna una ruta y un método HTTP a un handler. Encadene llamadas a .route(path, method(handler)) para registrar endpoints. Los helpers de métodos, como get, post, put y delete, proceden de axum::routing. Puede combinar métodos en la misma ruta.
use axum::{routing::{get, post}, Router};
async fn list() -> &'static str { "list" }
async fn create() -> &'static str { "created" }
fn build_router() -> Router {
Router::new()
.route("/items", get(list).post(create))
.route("/health", get(|| async { "ok" }))
}Estructura de módulos recomendada
A medida que la API crece, divida el código en módulos en lugar de mantener un único main.rs enorme:
main.rs— inicio y configuración del servidor.routes.rs— definición del router.handlers.rs— handlers de las solicitudes.models.rs— estructuras de datos.
Esta separación mantiene cada archivo centrado y facilita las pruebas.
// src/main.rs
mod routes;
mod handlers;
mod models;
#[tokio::main]
async fn main() {
let app = routes::build();
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
.await.unwrap();
axum::serve(listener, app).await.unwrap();
}Estado compartido de la aplicación
La mayoría de las API necesitan un estado compartido, como un pool de conexiones a una base de datos o un almacén en memoria. Axum lo incorpora mediante .with_state(state) en el router. Los handlers lo reciben mediante el extractor State. El estado debe ser Clone; envuelva los datos mutables en un Arc y un mecanismo de bloqueo.
use axum::{routing::get, Router, extract::State};
use std::sync::{Arc, Mutex};
type Db = Arc<Mutex<Vec<String>>>;
async fn count(State(db): State<Db>) -> String {
let n = db.lock().unwrap().len();
format!("{} items", n)
}
fn build(db: Db) -> Router {
Router::new().route("/count", get(count)).with_state(db)
}Devolver JSON
Para enviar JSON, envuelva un valor serializable en axum::Json. Si deriva Serialize en sus estructuras mediante serde, Axum establece automáticamente el tipo de contenido y el cuerpo correctos.
use axum::Json;
use serde::Serialize;
#[derive(Serialize)]
struct Status {
service: String,
healthy: bool,
}
async fn health() -> Json<Status> {
Json(Status { service: "api".into(), healthy: true })
}Configuración y puertos
Fijar el puerto en el código está bien para las demostraciones, pero los servicios reales leen la configuración del entorno. Use std::env::var con un valor predeterminado. Así puede cambiar la dirección de enlace sin recompilar y trabajar correctamente con contenedores.
use std::env;
async fn main_inner() {
let port = env::var("PORT").unwrap_or_else(|_| "3000".to_string());
let addr = format!("0.0.0.0:{}", port);
println!("binding to {}", addr);
// bind and serve with addr ...
}Reunir la configuración
Un inicio completo conecta todas las piezas: crea el router con las rutas y el estado compartido, lee el puerto, enlaza un listener y empieza a servir. Con este esqueleto preparado, las siguientes lecciones añadirán endpoints reales, modelos y persistencia.
use axum::{routing::get, Router};
use std::sync::{Arc, Mutex};
#[tokio::main]
async fn main() {
let db = Arc::new(Mutex::new(Vec::<String>::new()));
let app = Router::new()
.route("/health", get(|| async { "ok" }))
.with_state(db);
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
.await.unwrap();
axum::serve(listener, app).await.unwrap();
}Comprobación rápida
Ponga a prueba su comprensión de la configuración del proyecto.
Resumen
Ha configurado un proyecto de API REST en Rust:
- Use
cargo newy añadaaxum,tokioyserde. #[tokio::main]proporciona el entorno de ejecución async.- Un
Routerasigna rutas y métodos a handlers async. - Comparta datos con
.with_statey el extractorState. - Divida el código en módulos de rutas, handlers y modelos; lea el puerto del entorno.
Preguntas frecuentes
¿La lección «Configuración del proyecto» es gratis?
Sí — el texto completo de «Configuración del proyecto» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Learn Rust Coding, actualiza a CoddyKit PRO. El curso de Learn Rust Coding incluye 4 lecciones en total.
¿Qué aprenderé en «Configuración del proyecto»?
Estructurar la API Practicas Learn Rust Coding con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Learn Rust Coding?
No se requiere experiencia previa. Learn Rust Coding en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 4.
¿Cuánto tiempo toma la lección «Configuración del proyecto»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Learn Rust Coding?
Sí. Cada lección de Learn Rust Coding incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Configuración del proyecto
- Endpoints y modelos
- Integración con la base de datos
- Pruebas de la API