Cómo implementar una aplicación MERN en Heroku usando MongoDB Atlas

Introducción a MERN

En este artículo, crearemos e implementaremos una aplicación creada con la pila MERN en Heroku.

MERN, que significa MongoDB, Express, React y Node.js, es una pila de tecnología popular utilizada en la creación de aplicaciones web. Implica trabajo frontend (con React), trabajo backend (con Express y NodeJS) y una base de datos (con MongoDB).

Heroku, por otro lado, es una plataforma como servicio (PaaS) que permite a los desarrolladores construir, ejecutar y operar aplicaciones completamente en la nube.

Para la base de datos, usaremos MongoDB Atlas, que es un servicio de base de datos en la nube global para aplicaciones modernas. Esto es más seguro que MongoDB instalado localmente en nuestro servidor y también nos da espacio para más recursos en nuestros servidores.

Para la interfaz, crearemos una aplicación React simple que realiza solicitudes POST a una API para agregar un usuario, y también puede realizar solicitudes GET para obtener todos los usuarios.

Puede saltar a cualquier paso con la tabla de contenido que se enumera a continuación.

Tabla de contenido

  • Introducción a MERN
  • Empecemos a construir
  • Construyendo la aplicación React
  • Creando el Backend
  • Conectar la base de datos Atlas de MongoDB
  • Llamar a las API en la interfaz
  • Implementar en Heroku
  • Crea una aplicación Heroku
  • Configurar package.json
  • Envolver

Empecemos a construir

Construyendo la aplicación React

Nota: Antes de comenzar con nuestro proyecto, nodedebe estar instalado en su computadora. nodetambién nos proporciona npm, que se utiliza para instalar paquetes.

Instalar en pc create-react-app

create-react-app se utiliza para crear una aplicación de inicio React.

Si no lo ha create-react-appinstalado, escriba lo siguiente en la línea de comando:

npm i create-react-app -g 

La -gbandera instala el paquete globalmente.

Crea el directorio del proyecto

create-react-app my-project cd my-project 

Lo anterior crea un directorio 'mi-proyecto' e instala las dependencias que se utilizarán en la aplicación de inicio React. Una vez finalizada la instalación, el segundo comando cambia al directorio del proyecto.

Inicie la aplicación y realice las modificaciones necesarias

npm start 

El comando anterior inicia la aplicación React, que le brinda una URL donde puede obtener una vista previa del proyecto. A continuación, puede realizar las ediciones necesarias, como cambiar imágenes o texto.

Instalar axios

npm i axios --save 

axioses una biblioteca de JavaScript que se utiliza para facilitar las solicitudes HTTP. Se utilizará para enviar solicitudes desde el frontend (React) a las API proporcionadas por el backend.

Creando el Backend

El backend administra las API, maneja las solicitudes y también se conecta a la base de datos.

Instale los paquetes de backend

npm i express cors mongoose body-parser --save 
  1. express: "Express es un marco de trabajo de aplicación web Node.js mínimo y flexible que proporciona un conjunto sólido de funciones para aplicaciones web" - Documentación Express
  2. cors: "CORS es un paquete node.js para proporcionar un middleware Connect / Express que se puede utilizar para habilitar CORS con varias opciones" - Documentación de cors
  3. mongoose: "Mongoose es una herramienta de modelado de objetos de MongoDB diseñada para funcionar en un entorno asincrónico. Mongoose admite promesas y devoluciones de llamada" - Documentación de Mongoose
  4. body-parser: "Middleware de análisis del cuerpo de Node.js". - Documentación del analizador corporal

Crea la carpeta de backend

mkdir backend cd backend 

Configurar el backend

Crea un punto de entrada server.js

Primero, cree un server.jsarchivo, que será el punto de entrada al backend.

touch server.js 

En server.js, escriba lo siguiente:

const express = require('express'); const bodyParser = require('body-parser'); const cors = require('cors'); const path = require('path') const app = express(); require('./database'); ----- app.use(bodyParser.json()); app.use(cors()); ----- // API const users = require('/api/users'); app.use('/api/users', users); ----- app.use(express.static(path.join(__dirname, '../build'))) app.get('*', (req, res) => { res.sendFile(path.join(__dirname, '../build')) }) ----- const port = process.env.PORT || 5000; app.listen(port, () => { console.log(`Server started on port ${port}`); }); 

express.staticentrega archivos estáticos que son los que se crean cuando npm run buildse ejecuta en un proyecto de React. Recuerde, el archivo construido está en la carpeta de construcción.

Desde nuestra configuración, cualquier solicitud enviada a /api/usersse enviará a la usersAPI que estamos a punto de configurar.

Configurar la usersAPI
mkdir api touch api/users.js 

En api/users.js, agregue lo siguiente:

const express = require('express'); const router = express.Router() ----- const User = require('../models/User'); ----- router.get('/', (req, res) => { User.find() .then(users => res.json(users)) .catch(err => console.log(err)) }) ----- router.post('/', (req, res) => { const { name, email } = req.body; const newUser = new User({ name: name, email: email }) newUser.save() .then(() => res.json({ message: "Created account successfully" })) .catch(err => res.status(400).json({ "error": err, "message": "Error creating account" })) }) module.exports = router 

En el código anterior, creamos un controlador de solicitudes GET y POST que busca a todos los usuarios y los publica. El Usermodelo que crearemos ayuda a recuperar y agregar un usuario a la base de datos .

Crear Usermodelo
mkdir models touch models/user.js 

En models/user.js, agregue lo siguiente:

const mongoose = require('mongoose'); const Schema = mongoose.Schema; ----- const userSchema = new Schema({ name: { type: String, required: true }, email: { type: String, required: true } }) module.exports = mongoose.model("User", userSchema, "users") 

En el código anterior, se crea un esquema para el usuario que contiene los campos del usuario. Al final del archivo, el modelo ("Usuario") se exporta con el esquema y la colección ("usuarios").

Conectar la base de datos Atlas de MongoDB

Según los documentos, "MongoDB Atlas es el servicio de base de datos en la nube global para aplicaciones modernas".

Primero debemos registrarnos en Mongo Cloud. Consulte esta documentación para crear una cuenta Atlas y crear su clúster.

Una cosa que vale la pena señalar es incluir en la lista blanca su dirección IP de conexión . Si ignora este paso, no tendrá acceso al clúster, así que preste atención a ese paso.

El clúster es un pequeño servidor que administrará nuestras colecciones (similar a las tablas en las bases de datos SQL). Para conectar su backend al clúster, cree un archivo database.js, que como puede ver se requiere en server.js. Luego ingrese lo siguiente:

const mongoose = require('mongoose'); const connection = "mongodb+srv://username:@/?retryWrites=true&w=majority"; mongoose.connect(connection,{ useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false}) .then(() => console.log("Database Connected Successfully")) .catch(err => console.log(err)); 

En la connectionvariable, ingrese su username(para la nube MongoDB), su password(contraseña de clúster), su cluster(dirección de su clúster) y el database(nombre de su base de datos). Todos estos se pueden descubrir fácilmente si siguió la documentación.

Llamar a las API en la interfaz

Todas las API estarán disponibles localhost:5000localmente, tal como las configuramos en server.js. Cuando se implementa en Heroku, el servidor utilizará el puerto proporcionado por el servidor ( process.env.PORT).

Para facilitar las cosas, React nos permite especificar un proxy al que se enviarán las solicitudes.

Abra package.jsony justo antes de la última llave, agregue lo siguiente:

"proxy": "//localhost:5000" 

De esta forma podemos enviar solicitudes directamente a api/users. Y cuando nuestro sitio esté implementado y construido, el puerto predeterminado de nuestra aplicación se utilizará con la misma API.

Abra App.jspara React y agregue lo siguiente:

import React, {useState, useEffect} from 'react' import axios from 'axios'; ----- const App = function () { const [users, setUsers] = useState(null); const [username, setUsername] = useState(""); const [email, setEmail] = useState(""); useEffect(() => { axios .get("/api/users") .then((users) => setUsers(users)) .catch((err) => console.log(err)); }, []); function submitForm() { if (username === "") { alert("Please fill the username field"); return; } if (email === "") { alert("Please fill the email field"); return; } axios .post("/api/users", { username: username, email: email, }) .then(function () { alert("Account created successfully"); window.location.reload(); }) .catch(function () { alert("Could not creat account. Please try again"); }); } return (  

My Project

{users === null ? (

Loading...

) : users.length === 0 ? (

No user available

) : (

Available Users

    {users.map((user, index) => (
  1. Name: {user.name} - Email: {user.email}
  2. ))}
)} setUsername(e.target.value)} type="text" placeholder="Enter your username" /> setEmail(e.target.value)} type="text" placeholder="Enter your email address" /> ); }; export default App

Los ganchos useStatey useEffectse utilizan para manejar el estado y sideEffects. Lo que está sucediendo básicamente es que el primer estado de los usuarios es nully se muestra 'Cargando ...' en el navegador.

En useEffect, []se usa para especificar que en la componentDidMountetapa (cuando se monta el componente), realice una solicitud de Axios a la API que se está ejecutando localhost:5000. Si obtiene el resultado y no hay ningún usuario, se muestra "Ningún usuario disponible". De lo contrario, se muestra una lista numerada de usuarios.

Si desea obtener más información sobre useStatey useEffect, consulte este artículo: ¿Qué diablos es React Hooks?

With the form available, a POST request can be made to post a new user. The state of the inputs are controlled and sent to the API at localhost:5000 on submission. Afterwards, the page is refreshed and the new user is displayed.

Deploying to Heroku

To deploy your application to Heroku, you must have a Heroku account.

Go to their page to create an account. Then go through their documention on how to create a Heroku app. Also check out the documentation on Heroku CLI.

Create a Heroku App

First, login to Heroku:

heroku login 

This will redirect you to a URL in the browser where you can log in. Once you're finished you can continue in the terminal.

In the same React project directory, run the following:

heroku create 

This will create a Heroku application and also give you the URL to access the application.

Configure package.json

Heroku uses your package.json file to know which scripts to run and which dependencies to install for your project to run successfully.

In your package.json file, add the following:

{ ... "scripts": { ... "start": "node backend/server.js", "heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install npm && run build" }, ... "engines": { "node": "10.16.0" } } 

Heroku runs a post build, which as you can see installs your dependencies and runs a build of your React project. Then it starts your project with the start script which basically starts your server. After that, your project should work fine.

engines specifies the versions of engines like node and npm to install.

Push to Heroku

git push heroku master 

This pushes your code to Heroku. Remember to include unnecessary files in .gitignore.

After few seconds your site will be ready. If there are any errors, you can check your terminal or go to your dashboard in the browser to view the build logs.

Now you can preview your site at the URL Heroku sent when you ran heroku create.

That's all there is to it. Glad you read this far.

Wrap Up

Of course there is more to MERN stack applications.

This article did not go as deep as authentications, login, sessions, and all that. It just covered how to deploy MERN stack applications to Heroku and work with MongoDB Atlas.

You can find other articles like this on my blog - dillionmegida.com

Thanks for reading.