Introducción al Frontend en el proyecto
A partir de hoy, vamos a estar integrando el backend que veníamos desarrollando a una interfaz de usuario hecha con html + css + javascript. Para ello, vamos a tener que crear una nueva carpeta que contenga el frontend. Si bien siempre que se entienda, cualquier separación es correcta, vamos a ofrecer 3 opciones para que tengan en cuenta:
- Separar el backend y el frontend en carpetas distintas: Para esto, todo lo que veníamos haciendo lo vamos a colocar en la carpeta
backend
y todo lo que vayamos a hacer relacionado con el frontend lo vamos a poner en la carpetafrontend
. Ambas carpetas se suben a un mismo repo - Separar el backend y el frontend en repositorios diferentes: Lo mismo que lo anterior, pero ambas carpetas se suben a repositorios distintos
- Crear una carpeta
public
dentro del proyecto que ya tenemos, y dentro de ella poner todo lo relacionado con el frontend. Esta es la solución que vamos a usar para los ejemplos del blog
En cualquier caso, la carpeta que se elija contendrá los archivos html, css y js que vamos a usar para hacer la interfaz de usuario.
Configuración previa
Antes de comenzar con la interfaz de usuario, vamos a tener que permitir cors en el backend. Para ello, vamos a tener que hacer uso de la libreria cors
, que nos permite recibir solicitudes http de distintos dominios (como el de nuestro frontend)
npm install cors
Y luego en el archivo de nuestra API express:
import express from 'express';
import routes from './routes/index.js';
import cors from 'cors'; // Importamos cors
const app = express();
// Middlewares
app.use(express.json()); // Para poder leer el req.body
app.use(cors()); // Para permitir cors
// Rutas
app.use(routes);
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`Mi aplicacion esta funcionando en http://localhost:${port}`);
})
Creación de la carpeta frontend
Vamos a crear la carpeta donde va a ir la interfaz de usuario, y dentro de ella, vamos a crear los archivos que vamos a usar para hacer la interfaz de usuario.
|-generated
|-lib
|-prisma
|-public
|--css
|---styles.css
|--js
|---api
|----tareas.js // Interacción con el backend para las tareas
|--pages
|---tareas
|----index.html // Listado de tareas
|----create.html // Formulario para crear tareas
|--index.html // Pag. principal de su aplicación
|-routes
|-.env
|-.gitignore
|-index.js
|-package.json
Archivo api.js
Es el archivo que va a hacer la interacción con el backend. En principio, vamos a tener solo un archivo que va a hacer la interacción con el backend para las tareas, y vamos a llamarlo tareas.js
Este archivo va a hacer uso de un comando de javascript llamado fetch
, que nos va a permitir hacer solicitudes http a la API. Este comando toma 2 parametros, siendo el primero la URL de la API y el segundo (opcional) un objeto con la configuración de la llamada.
// public/js/api/tareas.js
const API_URL = 'http://localhost:8000/tareas' // URL de la API
export async function getTareas() {
// Llamada a la API
const response = await fetch(API_URL)
const tareas = await response.json()
return tareas // Devuelve las tareas
}
export async function createTarea(tarea) {
// Llamada a la API
const response = await fetch(API_URL, {
method: 'POST', // Metodo HTTP
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(tarea) // Cuerpo de la llamada (los datos que enviaremos al backend)
})
const data = await response.json()
return data;
}
Uso de las funciones en el HTML
Para usarlo, vamos a tener que importarlo dentro de nuestro documento html pages/tareas/index.html
haciendo uso de la etiqueta <script type="module">
. De la siguiente forma
Listado de tareas
<!DOCTYPE html>
<head>
<title>LIstado de tareas</title>
</head>
<body>
<h1>Listado de tareas</h1>
<a href="./create.html">Crear nueva</a>
</body>
<script type="module">
import { getTareas } from "../../api/tareas.js"; // Importamos la funcion getTareas
document.addEventListener('DOMContentLoaded', async () => { // Cuando se cargue el DOM
const tareas = await getTareas() // Obtenemos las tareas
console.log(tareas) // Imprimimos las tareas
})
</script>
</html>
Tengan en cuenta que el hecho de poder tener una variable con el listado de tareas es más que suficiente para ser capaces de acceder a las tareas y, más adelante, manipularlas en la interfaz. Mostrarlas en consola es solo una demo de las posibilidades que tenemos.
Crear una nueva tarea:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Crear tarea</h1>
<form id="crear-tarea-form">
<label for="titulo">Titulo</label>
<input type="text" id="titulo" name="titulo">
<label for="descripcion">Descripcion</label>
<input type="text" id="descripcion" name="descripcion">
<label for="path">Path</label>
<input type="text" id="path" name="path">
<button type="submit">Crear</button>
</form>
</body>
<script type="module">
import { createTarea } from '../../api/tareas.js'
const form = document.getElementById('crear-tarea-form') // Obtenemos el formulario
form.addEventListener('submit', async (e) => { // Cuando se envie el formulario
e.preventDefault() // Evitamos que la página se recargue
const formData = new FormData(form) // Obtenemos los datos del formulario
const tarea = { // Creamos el objeto de la tarea
titulo: formData.get('titulo'),
descripcion: formData.get('descripcion'),
path: formData.get('path')
}
await createTarea(tarea) // Creamos la tarea en el backend
console.log("Tarea creada con exito!") // :D
})
</script>
</html>