Está en la página 1de 26

GUIA PRACTICA CRUD – DESARROLLO WEB

Tabla de Contenidos
Requerimientos .............................................................................................................................. 3
Especificaciones .............................................................................................................................. 3
Procedimiento ................................................................................................................................ 4
Backend .................................................................................................................................................. 4
Creación de base de datos en MongoDB Atlas..................................................................................................... 4
Inicialización del proyecto general ....................................................................................................................... 8
Creación de la estructura del proyecto basada en MVC ...................................................................................... 9
Creación de servidor ........................................................................................................................................... 10
Creación de variables de entorno ...................................................................................................................... 11
Construcción del modelo .................................................................................................................................... 11
Construcción de la vista/rutas ............................................................................................................................ 12
Unión del patrón MVC con el servidor ............................................................................................................... 14
Inicialización del servidor ................................................................................................................................... 15
Frontend............................................................................................................................................... 16
Inicialización del proyecto general ..................................................................................................................... 16
Creación de la estructura del proyecto .............................................................................................................. 17
Creación de servidor y página principal ............................................................................................................. 19
Creación de estilo principal ................................................................................................................................ 20
Creación de componentes .................................................................................................................................. 21
Inicialización del servidor ................................................................................................................................... 25

Resultado Final ............................................................................................................................. 25


Recursos ........................................................................................................................................ 26
Requerimientos
Con el fin de desarrollar un proyectoFull-Stackque cumpla con la línea de estudio propuesta por
el programa de MisiónTIC 2022 para el Ciclo 4A, se requiere que se cumpla los diferentes
requerimientos mostrados a continuación:

• Backend y Frontend desacoplados.

• Realizar por los dos componentes creados algún tipo de CRUD .

• Utilizar el conjunto de subsistemas conocido como MERN (MongoDB,Express JS,React JS


y NodeJS).

• Implementar la librería de estilo conocida como Bootstrap en la parte visual.

• Tener preparada una guía práctica que describa el proceso a seguir del desarrollo del
proyecto general.

• Dicha guía ser lo suficientemente corto para poder realizarse en 2.5 horas.

• Procurar no usar muchas librerías en el proyecto.

Especificaciones
Para el desarrollo del proyecto se necesita los siguientes programas, con el fin de cumplir con los
requerimientos solicitados por el programa:

• Visual Studio Code Version 1.72.2


• MongoDB Version 6.0.2
• MongoDB Compass Version 1.33.1
• NodeJS Version 16.18.0
Procedimiento

Backend

Creación de base de datos en MongoDB Atlas

Para iniciar dicho desarrollo, empezaremos a crear una base de datos en línea mediante la
herramientaAtlasproveída por la empresa y base de datosMongoDB, la cual nos permitirá tener
un alojamiento de tipo clúster gratuito que recibirá todas las solicitudes por parte del cliente.

Primero accedemos a la página deMongoDB Atlasdonde luego creamos una cuenta con ellos.
Escogemos la opción de Clúster y finalmente ingresamos al panel proveído por la plataforma.
Finalmente cambiamos las IP de acceso para fácil acceso y con esto obtenemos el link de acceso
a nuestra base de datos , la cual utilizaremos más adelante.
Inicialización del proyecto general

Para iniciar dicho proyecto debemos tener una carpeta enfocada a solamente elBackend, con el
fin de tener más control de los diferentes recursos proveídos para la página. Dicha estructura
debería verse de la siguiente manera:
Con esto , simplemente vamos a abrir la carpeta general enVisual Studio Codey abrimos la
terminal, donde nos dirigimos a la carpeta designada para elBackendy inicializamos un
proyecto deNodeJSmediante el siguiente comando :

npm init

Con dicho comando , ya podemos empezar a instalar las siguientes dependencias requeridas para
el manejo general del programa, lo cual lo podemos realizar de la siguiente manera :

npm i express mongoose nodemon dotenv

Las dependencias instaladas estan enfocadas en manejo de comandos de JavaScript , manejo


orientado a objetos paraMongoDB, ambiente de desarrollo paraNodeJSy variables de entorno
para los accesos a la base de datos.

Creación de la estructura del proyecto basada en MVC

Con el fin de mantenernos en el flujo MVC debemos crear las carpetas para los modelos y las
rutas, pues al fin al cabo nuestraVista – Controladorse resumirá en losendpoints/rutasque el
cliente utilizará. Dicha estructura debería ser parecida a la mostrada brevemente:
Creación de servidor

Al ser un servidor que funcionará de intermediario entre nuestra base de datos y el cliente, este
necesitará de una configuración general para inicializarse, donde para este ejercicio crearemos un
archivo en la raíz llamadoindex.js, el cual almacenará nuestras configuraciones de inicialización
del servidor.

Para este ejercicio se hará una estructura sencilla en la cual utilice variables de entorno, inicialice
el servidor y se conecte a la base de datos. Dicha estructura del archivo será de la siguiente
manera:

//IMPORTACION DE DEPENDENCIAS
const express = require('express');
const mongoose = require('mongoose');
const app = express();

require('dotenv').config();

//DECLARACIÓN DE USO JSON

app.use(express.json());

//CONEXION A BASE DE DATOS

const mongoString=process.env.DATABASE_URL;
mongoose.connect(mongoString);
const database=mongoose.connection;

database.on('error',(error)=>{
console.log(error);
})

database.once('connected',()=>{
console.log('Base de datos conectada');
})
//INICIACIÓN DE SERVIDOR EN PUERTO ESTABLECIDO

app.listen(process.env.PORT || 5000)

Creación de variables de entorno

Como nos podemos dar cuenta, el archivo de iniciación tiene variables de entorno con el fin de
proteger la información a prestar. Por ende para crear estas variables se crea un archivo.enven la
raíz de la carpeta. Dicho archivo debe quedar creado así:

Para la creación de las variables se hará de la siguiente manera:

Construcción del modelo

Terminado los pasos anteriores, crearemos en el archivomodelo.jsla estructura de nuestra base


de datos a modo de esquema (Schema), en la cual se hará de la siguiente manera:

const mongoose = require('mongoose');

const dataSchema=new mongoose.Schema({


titulo:{
required:true,
type:String
},
estado:{
required:true,
type:String
},
descripcion:{
required:true,
type:String
}
})

module.exports=mongoose.model('Data',dataSchema);

Construcción de la vista/rutas

Para las rutas haremos una importación sencilla de nuestro modelo y conExpressJSmanejamos
las rutas generales (GET, PUT, PATCH & DELETE) , las cuales exportamos para ser
implementadas en el servidor principal. Dicha estructura debe quedar de la siguiente manera:

const express=require('express');
const router = express.Router();
const Model=require('../model/model');

//Get all method


router.get('/get',async (req,res)=>{
try{
const data=await Model.find();
res.json(data);

}
catch(error){
res.status(500).json({
message:error.message
})
}

})

//Get by id
router.get('/get/:id', async (req,res)=>{
try{
const data= await Model.findById(req.params.id);
res.json(data);

}
catch(error){
res.status(500),json({
message:error.message
})

}
})

//Update by id
router.patch('/update/:id', async(req,res)=>{
try{
const id=req.params.id;
const updateData=req.body;
const options= {new:true};

const result= await Model.findByIdAndUpdate(


id,updateData,options
)
res.send(result);
}
catch(error){
res.status(400).json({
message:error.message
})

}
})
//Post Method
router.post('/post', async (req,res)=>{
const data=new Model({
titulo:req.body.titulo,
estado:req.body.estado,
descripcion:req.body.descripcion
})

try{
const dataToSave = await data.save();
res.status(200).json(dataToSave);

}
catch(error){
res.status(400).json({message:error.message});

}
})

//Delete method by id
router.delete('/delete/:id', async (req,res)=>{
try{
const id= req.params.id
const data = await Model.findByIdAndDelete(id);
res.send('Eliminado');
}
catch(error){
res.status(400).json({
message:error.message
})
}
})
module.exports=router;

Unión del patrón MVC con el servidor

Como nuestro modelo lo importa la vista-controlador, simplemente importamos el módulo al


servidor principal. Al final, nuestroindex.jsdebe quedar de la siguiente manera:

//IMPORTACION DE DEPENDENCIAS
const express = require('express');
const mongoose = require('mongoose');
const app = express();

require('dotenv').config();

//DECLARACIÓN DE USO JSON

app.use(express.json());

//CONEXION A BASE DE DATOS

const mongoString=process.env.DATABASE_URL;
mongoose.connect(mongoString);
const database=mongoose.connection;

database.on('error',(error)=>{
console.log(error);
})

database.once('connected',()=>{
console.log('Base de datos conectada');
})

//Importacion rutas
const routes=require('./routes/routes');
app.use('/api',routes);
//INICIACIÓN DE SERVIDOR EN PUERTO ESTABLECIDO

app.listen(process.env.PORT || 5000)
Inicialización del servidor

Para iniciar el servidor creamos un Script en nuestropackage.jsonpara que inicialice en modo


desarrollador. Dichos comandos deben quedar como en la siguiente estructura:

"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "nodemon index.js"
},

Finalmente, el servidor se inicializa y debe poder realizar un CRUD mediante losendpoints


establecidos:
Frontend

Inicialización del proyecto general

Para iniciar dicho proyecto debemos tener una carpeta enfocada a solamente elFrontend, con el
fin de tener más control de los diferentes recursos proveídos para la página frontal. Dicha
estructura debería verse de la siguiente manera:

Con esto , simplemente vamos a abrir la carpeta general enVisual Studio Codey abrimos la
terminal, donde nos dirigimos a la carpeta designada para elFrontende inicializamos un
proyecto deNodeJSmediante el siguiente comando :

npx create-react-appreact-crud

Con dicho comando , ya podemos iniciar el servidor de React con el siguiente comando :

npm start

Al ejecutar el comando , nuestro servidor deReactJSdebe ser accesible por ellocalhost:3000,


donde nuestra vista principal será la siguiente:
Creación de la estructura del proyecto

Con el fin de mantenernos en el flujo de componentes, crearemos una carpeta para estos mismos,
pues con esto podremos crear las funciones necesarias para el manejo de la parte frontal con los
endpointsanteriormente creados. Para este ejercicio crearemos los principales archivos de
JavaScript, donde luego los modificaremos para su correcto funcionamiento. Dicha estructura
debería ser parecida a la mostrada brevemente:
Creación de servidor y página principal

Al ser un servidor que funcionará de intermediario entre nuestra base de datos y el cliente, este
necesitará de una configuración general para inicializarse, donde para este ejercicio vamos a
manejar los archivosapp.jsyindex.js, el cual almacenará la vista principal y nuestras
configuraciones de inicialización del servidor.

Para este ejercicio se hará una estructura sencilla en la cual establezca la estructura de la vista
principal y ejecución del servidor. Dicha estructura del archivo será de la siguiente manera:

App.js
import './App.css';
import Create from './components/create';
import Read from './components/read';
import Update from './components/update';
import { BrowserRouter as Router, Route } from 'react-router-dom';

function App() {
return (
<Router>
<div className="main">
<h2 className="main-header">CRUD Tickets MERN</h2>
<div>

</div>
<div>
<Create/>
</div>
</div>
</Router>
);
}

export default App;

index.js

import React from 'react';


import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));


root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function


// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

Creación de estilo principal

Para que la pagina cargue de manera correcta vamos a crear una hoja de estilos, el cual contenga
la definición de todos los elementos que cargará la página web.

Dicho estilo tendrá la siguiente estructura:

app.css

.App {
text-align: center;
}

.App-logo {
height: 40vmin;
pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {


.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}

.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}

.App-link {
color: #61dafb;
}

@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

.main{
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #212121;
color: whitesmoke;
flex-direction: column;
}

.create-form label{
color: whitesmoke !important;
font-family: 'Montserrat', sans-serif;
font-size: 12px !important;
}

Creación de componentes

Para poder hacer manejo delendpointrealizado, debemos crear un componente por cada proceso
que vayamos a hacer, pues este contendrá todo el manejo de las solicitudes y
creación/visualización en la parte frontal.

Dichos archivos tendrán la siguiente estructura:

create.js

import React, { useState } from 'react';


import { Button, Form } from 'react-bootstrap';
import axios from 'axios';

function Create() {
const [titulo, setTitulo] = useState('');
const [estado, setEstado] = useState('');
const [descripcion, setDescripcion] = useState('');
const postData = () => {
axios.post('https://back-endciclo4a.herokuapp.com/api/post',{
titulo,
estado,
descripcion
})
console.log(titulo);
console.log(estado);
console.log(descripcion);
}
return (
<Form>
<Form.Group className="mb-3">
<Form.Control placeholder="Titulo" onChange={(e)=>
setTitulo(e.target.value)}/>
</Form.Group>
<Form.Group className="mb-3">
<Form.Control placeholder="Estado" onChange={(e)=>
setEstado(e.target.value)}/>
</Form.Group>
<Form.Group className="mb-3">
<Form.Control placeholder="Descripcion" onChange={(e)=>
setDescripcion(e.target.value)}/>
</Form.Group>
<Button variant="primary" type="submit" onClick={postData}>
Submit
</Button>
</Form>
);
}

export default Create;

read.js

import React, { useEffect, useState } from 'react';


import { Button,Table} from 'react-bootstrap';
import axios from 'axios';

export default function Read() {


const [APIData, setAPIData] = useState([]);
useEffect(() => {
axios.get(`https://back-endciclo4a.herokuapp.com/api/get`)
.then((response) => {
console.log(response.data)
setAPIData(response.data);
})
}, []);

const setData = (data) => {


let {titulo, estado, descripcion} = data;
localStorage.setItem('titulo', titulo);
localStorage.setItem('estado', estado);
localStorage.setItem('descripcion', descripcion);
}

const getData = () => {


axios.get(`https://back-endciclo4a.herokuapp.com/api/get`)
.then((getData) => {
setAPIData(getData.data);
})
}

const onDelete = (id) => {


axios.delete(`https://back-endciclo4a.herokuapp.com/api/getOne/${id}`)
.then(() => {
getData();
})
}

return (
<div>
<Table singleLine>
<Table.Header>
<Table.Row>
<Table.HeaderCell>Titulo</Table.HeaderCell>
<Table.HeaderCell>Estado</Table.HeaderCell>
<Table.HeaderCell>Descripcion</Table.HeaderCell>
</Table.Row>
</Table.Header>

<Table.Body>
{APIData.map((data) => {
return (
<Table.Row>
<Table.Cell>{data.titulo}</Table.Cell>
<Table.Cell>{data.estado}</Table.Cell>
<Table.Cell>{data.descripcion}</Table.Cell>
<Table.Cell>
<Button onClick={() =>
onDelete(data.id)}>Eliminar</Button>
</Table.Cell>
</Table.Row>
)
})}
</Table.Body>
</Table>
</div>
)
}

Update.js
import React, { useState, useEffect } from 'react';
import { Button, Form } from 'react-bootstrap';
import axios from 'axios';
import { useNavigate } from 'react-router';

export default function Update() {


let history = useNavigate();
const [id, setID] = useState(null);
const [titulo, setTitulo] = useState('');
const [estado, setEstado] = useState('');
const [descripcion, setDescripcion] = useState('');

useEffect(() => {
setID(localStorage.getItem('ID'))
setTitulo(localStorage.getItem('Titulo'));
setEstado(localStorage.getItem('Estado'));
setDescripcion(localStorage.getItem('Descripcion'));
}, []);

const updateAPIData = () => {


axios.put(`https://back-endciclo4a.herokuapp.com/api/update/${id}`, {
titulo,
estado,
descripcion
}).then(() => {
history.push('/read')
})
}
return (
<div>
<Form className="create-form">
<Form.Field>
<label>Titulo</label>
<input placeholder='Titulo' value={titulo} onChange={(e) =>
setTitulo(e.target.value)}/>
</Form.Field>
<Form.Field>
<label>Estado</label>
<input placeholder='Estado' value={estado} onChange={(e) =>
setEstado(e.target.value)}/>
</Form.Field>
<Form.Field>
<label>Descripcion</label>
<input placeholder='Descripcion' value={descripcion} onChange={(e)
=> setDescripcion(e.target.value)}/>
</Form.Field>
<Button type='submit' onClick={updateAPIData}>Actualizar</Button>
</Form>
</div>
)
}

Inicialización del servidor

Para ejecutar el servidor frontal debemos escribir nuevamente el comando inicialmente


propuesto al inicio de este apartado , en el cual tendríamos la siguiente salida :

Resultado Final
Sí iniciamos los dos servicios de manera correcta , al igual que nuestro servidor frontal ,
debemos poder ingresar y ver la siguiente página:
Con esto podemos empezar a hacer los diferentes procesos disponibles en nuestra parte del
servidor.

Recursos
Para la revisión de dicho código se puede encontrar en el siguiente repositorio:

https://gitlab.com/misiontictutor15/crud_ciclo4a

También podría gustarte