En esta «learning» vamos a aprender cómo conectar con una base de datos en la nube, específicamente en MongoDB Atlas.
Vamos a crear un «proxy» en cloud.prisma.io
y lo vamos a utilizar con Remix y Cloudflare.
Lo único que necesitas para este ejercicio es: Node.js en tu terminal y una cuenta en cloudflare.com
Y vamos a hacerlo todo en 6 sencillos pasos. ¿Lista(o)? 🤓
Vamos al sitio en este enlace para iniciar sesión y crear un proyecto nuevo. Para luego crear una nueva base de datos.
Puedes generar usuarios en la pestaña Database Access
para luego dar clic en conect
y copiar el string
de conexión. Guardalo en un lugar seguro, o en un archivo .env
.
Vamos a crear un proxy para nuestra base de datos, esto para que así podamos consumirla con peticiones HTTP desde Cloudflare.
Ahora, inicia sesión en Prisma.io y crea un proyecto nuevo.
Aquí pegaremos el link de nuestra base de datos Mongo para luego generar este link. No olvides agregar el nombre de la base de datos al final del enlace, antes de los searchParams
.
Ahora guardamos este link en un lugar seguro o también en .env
.
👀 Esta será la única ocación que podremos consultar este string en la consola de Prisma. Guarda bien tu string. Jamás lo publiques.
Puedes hacer esto en algún proyecto ya inicializado con Remix, pero si no, recuerda que los pasos para crear un proyecto nuevo, son los siguientes:
npx create-remix@latest
No olvides seleccionar Cloudflare (pages o workers).
Agregamos nuestras variables a un archivo .env
y también a wrangler.toml
Colocar las variables en wrangler.toml
es importante para que se carguen de forma global y estén disponibles en Cloudflare.
Para terminar la configuración en el proyecto, vamos a inicializar nuestro esquema de Prisma, también vamos a escribir (o no: prisma db pull
) un par de modelos y una relación uno a muchos, solo como ejemplo.
Instalamos prisma como herramienta de desarrollo y también el cliente de prisma.
npm i prisma -D
npm i @prisma/client
Ahora vamos a generar el archivo de esquema con el comando:
npx prisma init
Lo que producirá un archivo prisma.schema
dentro de una carpeta prisma
. A este archivo le vamos a agregar nuestras variables de entorno de esta manera:
Toma nota del uso de las dos URL
.
La primera:url
, se usará con el cliente para consumir la base de datos programáticamente en tu código.
Mientras que directUrl
se utilizará con los comandos CLI de prisma, cuando estemos en desarrollo. Como son: npx prisma db push/pull/migrate
etc.
Así no perdemos funcionalidad. 🤓 Bueno, pues dale un
npx prisma db push
para subir tus nuevos modelos a tu DB.
Finalmente, generaremos el cliente de prisma para Cloudflare:
npx prisma generate --data-proxy
Muy bien, en un momento vamos a usar este cliente.
Vamos a crear una micro app para probar nuestra base de datos.
Después de iniciar sesión con Google (aquí esta el repo), vamos a dejar un comentario en el muro:
export const action: ActionFunction = async ({ request }) => {
const user = getUserOrRedirect(request);
const formData = await request.formData();
const text = formData.get("text");
// building 👨🏻💻
invariant(user && user.id);
const attempt = {
userId: user.id,
text,
};
// validating 🚫
const validated = commentSchema.safeParse(attempt);
if (!validated.success) return { ok: false, error: validated.error };
// saving 💾
await db.comment.create({ data: validated.data });
throw redirect("/");
};
export default function Index() {
return (
<main>
<Form>
<textarea placeholder="Deja un comentario" name="text"></textarea>
<button type="submit">{"Comentar"}</button>
</Form>
</main>
);
}
Al hacer submit del formulario vamos a recibirlo en un action
de Remix y vamos a guardarlo en nuestra base de datos con el cliente de Prisma.
👀 La conexión a la base de datos es HTTP gracias al Prisma proxy. Así que no hay problema con invocar al cliente en cada conexión, de todas formas Cloudflare administra el ciclo de vida de la función, la conexión siempre es efímera y el cliente se crea cada vez de todas formas. Pero si quieres puedes usar este formato para definir tu DB.
¡Genial! Ha sido muy fácil escribir en nuestra DB, ahora vamos a leerla.
type LoaderData = {
comments: CommentType[];
};
export const loader: LoaderFunction = async ({ request }) => {
await getUserOrRedirect(request);
const comments = await db.comment.findMany({
orderBy: { createdAt: "desc" },
});
return { comments };
};
export default function Index() {
// this is the real end to end Type saety
const { comments } = useLoaderData<LoaderData>();
return (
<main>
<section>
{comments.map((comment) => (
<p key={comment.id}>{comment.text}</p>
))}
</section>
<Form>
<textarea placeholder="Deja un comentario" name="text"></textarea>
<button type="submit">{"Comentar"}</button>
</Form>
</main>
);
}
Y así de fácil tenemos una micro app interactiva full stack con base de datos. 🔥🤯🤓
Además, gracias a que hemos colocado nuestros tipos correctamente, ahora tenemos type safty end-to-end
. 🔥
Y tenemos acceso al autocompletado. 🤯
Estamos listos para producción, con Cloudflare, siempre lo hemos estado. 👨🏼🎤
Me aseguro de que el comando "postinstall"
del archivo package.json
ejecute el comando de Prisma para la generación del cliente:
"postinstall": "npx prisma generate --data-proxy",
Esto nos asegura que si existiera algún build step
en Cloudflare, nuestro cliente de Prisma sería generado correctamente.
👀 Esto puede que no sea necesario en todos los casos. Con las versiones más recientes de Remix ya no es necesario.
¡Y ya, vamos a probar!
npm run deploy
Con tu cuenta de Cloudflare abierta, esto tomará un par de segundos y tu app estaría lista para producción.
Confirma que todo funciona iniciando sesión y agregando un nuevo comentario.
- Para que el login de Google funcione debes agregar tus propios secret.
- La URL de redireccionamiento para producción, se llama
PROD_REDIRECT_URL
- No olvides indicar el nombre de tu base de datos en tu link de mongo, regularmente no lo incluye.
- Finalmente, no olvides cambiar la variable
ENV
aproduction
o eliminarla por completo.
Y ya está, lo tienes todo para construir aplicaciones web de primer nivel, ¿ya viste que pinche rápido carga tu app en Cloudflare? Tienes mucho poder en tus manos. 👊🏼✊🏼👊🏼 Úsalo sabiamente 🥋
🌀 ¿Ya vez? Lo lograste.
Abrazo. bliss.