Introducción
En el ecosistema del desarrollo web moderno, combinar la potencia de Next.js para crear aplicaciones React renderizadas en servidor (SSR/SSG) con la flexibilidad de una base de datos NoSQL como MongoDB, y la sencillez de despliegue de Railway se ha vuelto una práctica muy extendida. En este tutorial detallado veremos paso a paso cómo:
- Configurar un proyecto en Railway.
- Provisionar una base de datos MongoDB en Railway.
- Crear una aplicación Next.js localmente y conectar con MongoDB.
- Implementar operaciones CRUD básicas usando Mongoose.
- Desplegar la aplicación en Railway, aprovechando variables de entorno y pipelines automáticos.
1. ¿Qué es Railway, Next.js y MongoDB
Railway es una plataforma de despliegue de aplicaciones que automatiza la creación de infraestructuras y bases de datos. Permite un workflow muy ágil con repositorios Git.
Next.js es un framework sobre React que facilita el server-side rendering, static generation y rutas API integradas.
MongoDB es una base de datos NoSQL basada en documentos JSON, ideal para esquemas flexibles y aplicaciones modernas.
2. Crear cuenta y proyecto en Railway
- Registrar en Railway con tu cuenta de GitHub o email.
- En el Dashboard, hacer clic en New Project y luego seleccionar Provision PostgreSQL (cambiaremos a MongoDB más adelante).
- Nombrar tu proyecto, por ejemplo next-mongo-tutorial.
3. Provisionar MongoDB en Railway
Como Railway ofrece un plugin de MongoDB, sigue estos pasos:
- Dentro de tu proyecto en Railway, haz clic en Plugins.
- Selecciona MongoDB y haz clic en Provision.
- Railway creará una base de datos y generará una URL de conexión (
MONGODB_URI). - Copia esa variable de entorno para usarla en tu aplicación Next.js.
4. Crear la aplicación Next.js localmente
Abre tu terminal y ejecuta:
npx create-next-app@latest next-mongo-app cd next-mongo-app
Este comando genera una estructura de proyecto con páginas, rutas API y configuración inicial.
5. Instalar dependencias esenciales
Dentro de next-mongo-app, instala Mongoose:
npm install mongoose
Mongoose nos brinda un ODM para definir esquemas y modelos de MongoDB de forma segura y tipada.
6. Configurar variables de entorno
Crea un archivo .env.local en la raíz del proyecto con:
| Variable | Descripción |
|---|---|
| MONGODB_URI | URL de conexión proporcionada por Railway |
| NEXT_PUBLIC_APP_NAME | Nombre visible de la aplicación (opcional) |
MONGODB_URI=mongodb srv://user:pass@cluster.mongodb.net/dbnameretryWrites=truew=majority NEXT_PUBLIC_APP_NAME=MiApp
7. Conectar a MongoDB con Mongoose
En la carpeta lib, crea dbConnect.js:
import mongoose from mongoose
let cached = global.mongoose
if (!cached) {
cached = global.mongoose = { conn: null, promise: null }
}
async function dbConnect() {
if (cached.conn) {
return cached.conn
}
if (!cached.promise) {
const opts = {
useNewUrlParser: true,
useUnifiedTopology: true
}
cached.promise = mongoose.connect(process.env.MONGODB_URI, opts).then(mongoose => mongoose)
}
cached.conn = await cached.promise
return cached.conn
}
export default dbConnect
8. Definir un esquema y modelo
En models/User.js:
import mongoose from mongoose
const UserSchema = new mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
createdAt: { type: Date, default: Date.now }
})
export default mongoose.models.User mongoose.model(User, UserSchema)
9. Crear rutas API para CRUD
Por ejemplo, en pages/api/users/[id].js:
import dbConnect from ../../../lib/dbConnect
import User from ../../../models/User
export default async function handler(req, res) {
const { method } = req
await dbConnect()
switch (method) {
case GET:
try {
const user = await User.findById(req.query.id)
if (!user) return res.status(404).json({ success: false })
res.status(200).json({ success: true, data: user })
} catch (error) {
res.status(400).json({ success: false })
}
break
case PUT:
try {
const user = await User.findByIdAndUpdate(req.query.id, req.body, { new: true, runValidators: true })
if (!user) return res.status(404).json({ success: false })
res.status(200).json({ success: true, data: user })
} catch (error) {
res.status(400).json({ success: false })
}
break
case DELETE:
try {
const deletedUser = await User.deleteOne({ _id: req.query.id })
if (!deletedUser) return res.status(404).json({ success: false })
res.status(200).json({ success: true, data: {} })
} catch (error) {
res.status(400).json({ success: false })
}
break
default:
res.status(405).json({ success: false })
break
}
}
10. Probar localmente
- Ejecuta
npm run dev. - Accede a
http://localhost:3000/api/users. - Usa Postman o Insomnia para enviar peticiones CRUD y verificar la conexión.
11. Despliegue en Railway
- Enlaza tu repositorio GitHub con Railway (opción Deploy from GitHub).
- Asegúrate de definir
MONGODB_URIen Settings gt Variables. - Railway detectará el proyecto Next.js y ejecutará
npm installynpm run buildautomáticamente. - Accede a la URL asignada para ver tu aplicación en producción.
12. Buenas prácticas y seguridad
- No comites tu
.env.localal repositorio. - Utiliza indexes en campos clave (por ejemplo,
email). - Valida y sanitiza entradas para evitar injection.
- Configura roles de usuario y autenticación (por ejemplo, con NextAuth.js).
- Monitorea logs y métricas en Railway para identificar errores o cuellos de botella.
Conclusión
La integración de Railway con Next.js y MongoDB ofrece un flujo de trabajo simplificado, desde el desarrollo local hasta el despliegue en producción. Hemos cubierto la creación del proyecto, la configuración de la base de datos, la implementación de rutas API, pruebas locales y el despliegue continuo. Con estas herramientas, tu equipo podrá iterar rápidamente y escalar sin complicaciones de infraestructura.
Para seguir profundizando, revisa la documentación oficial de Next.js, Mongoose y los docs de Railway. ¡Manos a la obra y éxito en tu próximo proyecto!
Leave a Reply