Definir el límite del servidor
El backend ofrece a la interfaz un lugar fiable para solicitar trabajo. Con Node.js y Express aprenderás cómo una ruta recibe una petición, aplica la lógica de la aplicación y devuelve una respuesta útil. Mantener ese límite claro separa la presentación de las reglas y del tratamiento de datos.
Dar a los datos un lugar duradero
MongoDB introduce el almacenamiento de datos orientado a documentos. El trabajo consiste en decidir qué información pertenece junta, cómo se relacionan los registros con la aplicación y cómo el servidor los consulta o actualiza. Una capa de datos bien diseñada hace que la aplicación sirva más allá de una sesión del navegador.
Conectar la identidad con las acciones protegidas
La autenticación forma parte del flujo de la aplicación, no solo de una pantalla de acceso. JWT y Google OAuth cumplen funciones distintas: uno representa una sesión autenticada y el otro permite establecer la identidad mediante Google. La etapa conecta rutas, datos e identidad en una aplicación dinámica.
Del concepto al código funcional
Estos fragmentos muestran cómo aparecen en proyectos reales los conceptos de cada nivel. Son puntos de partida para leer, cuestionar, adaptar y probar; no código para copiar sin entenderlo.
Validar en el límite del servidor
La ruta toma el identificador del taller desde la URL y valida los datos antes de escribir. Distingue entradas no válidas, taller inexistente y creación correcta mediante estados HTTP diferentes.
router.post("/workshops/:id/registrations", async (req, res) => {
const { name, email } = req.body;
const workshopId = req.params.id;
if (!name?.trim() || !/^\S+@\S+\.\S+$/.test(email ?? "")) {
return res.status(400).json({ error: "Name and valid email required." });
}
const workshop = await workshops.findOne({ _id: workshopId });
if (!workshop) return res.status(404).json({ error: "Workshop not found." });
const registration = await registrations.insertOne({
workshopId,
name: name.trim(),
email: email.toLowerCase(),
createdAt: new Date(),
});
return res.status(201).json({ id: registration.insertedId });
});Separar la persistencia en un repositorio
El repositorio centraliza las operaciones de MongoDB y ofrece una interfaz pequeña al resto de la aplicación. Así la ruta es más fácil de entender y el almacenamiento se puede cambiar o probar en un solo lugar.
export function createRegistrationRepository(db) {
const registrations = db.collection("registrations");
return {
async create(input) {
const result = await registrations.insertOne({
workshopId: input.workshopId,
name: input.name.trim(),
email: input.email.toLowerCase(),
status: "pending",
createdAt: new Date(),
});
return { id: result.insertedId.toString(), status: "pending" };
},
findForWorkshop(workshopId) {
return registrations.find({ workshopId }).toArray();
},
};
}Léelo y después adáptaloCambia un requisito, predice el resultado y ejecuta el código para comprobarlo. En la revisión, explica la decisión tomada y una mejora que harías después.