Pasar a Jamstack con React, Serverless y Airtable

Índice
  1. ¿Por qué estas tecnologías?, te preguntarás.
  2. lo que estamos construyendo
  3. Configuración de la mesa de aire
  4. Configuración del proyecto
  5. Configurar funciones sin servidor
  6. Actualizando el archivo de configuración de Airtable
  7. Obtener cursos
  8. Creando cursos
  9. Actualización de cursos
  10. Eliminar cursos
  11. Mostrando una lista de cursos en React
  12. Agregar cursos en React
  13. Actualización de cursos comprados en React
  14. Eliminar cursos en React
  • Implementación en Netlify
  • ¡Bienvenido a Jamstack!
  • La mejor manera de aprender es construir. Aprendamos sobre esta nueva palabra de moda, Jamstack, creando un sitio con React, Netlify (Serverless) Functions y Airtable. Uno de los ingredientes de Jamstack es el alojamiento estático, pero eso no significa que todo en el sitio tenga que ser estático. De hecho, vamos a crear una aplicación con capacidad CRUD completa, tal como lo haría un tutorial para cualquier tecnología web con acceso más tradicional del lado del servidor.

    ¿Por qué estas tecnologías?, te preguntarás.

    Quizás ya lo sepas, pero “JAM” en Jamstack significa JavaScript, API y marcado. Estas tecnologías individualmente no son nuevas, por lo que Jamstack es en realidad solo una forma nueva y creativa de combinarlas. Puede leer más al respecto en el sitio de Jamstack.

    Uno de los beneficios más importantes de Jamstack es la facilidad de implementación y alojamiento, que influyen en gran medida en las tecnologías que utilizamos. Al incorporar las funciones de Netlify (para operaciones CRUD backend con Airtable), podremos implementar nuestra aplicación completa en Netlify. La simplicidad de este proceso es la belleza de Jamstack.

    En cuanto a la base de datos, elegí Airtable porque quería algo con lo que fuera fácil empezar. Tampoco quería atascarme en los detalles técnicos de la base de datos, por lo que Airtable encaja perfectamente. Estos son algunos de los beneficios de Airtable:

    1. No es necesario que implemente ni aloje una base de datos usted mismo
    2. Viene con una GUI similar a Excel para ver y editar datos.
    3. Hay un buen SDK de JavaScript

    lo que estamos construyendo

    Para mayor contexto, vamos a crear una aplicación que podrá utilizar para realizar un seguimiento de los cursos en línea que desee realizar. Personalmente, tomo muchos cursos en línea y, a veces, es difícil mantenerme al día con los que tengo pendientes. Esta aplicación permitirá realizar un seguimiento de esos cursos, de forma similar a una cola de Netflix.

    código fuente

    Una de las razones por las que tomo muchos cursos en línea es porque hago cursos. De hecho, tengo uno nuevo disponible donde puedes aprender cómo crear aplicaciones Jamstack seguras y listas para producción usando las funciones React y Netlify (sin servidor). Cubriremos la autenticación, el almacenamiento de datos en Airtable, los componentes con estilo, la integración continua con Netlify y más. Compruébalo →

    Configuración de la mesa de aire

    Permítanme comenzar aclarando que Airtable llama a sus bases de datos “bases”. Entonces, para comenzar con Airtable, necesitaremos hacer un par de cosas.

    1. Regístrese para obtener una cuenta gratuita
    2. Crea una nueva “base”
    3. Definir una nueva tabla para almacenar cursos.

    A continuación, creemos una nueva base de datos. Iniciaremos sesión en Airtable, haremos clic en “Agregar una base” y elegiremos la opción “Comenzar desde cero”. Llamé a mi nueva base “JAMstack Demos” para poder usarla para diferentes proyectos en el futuro.

    A continuación, hagamos clic en la base para abrirla.

    Notarás que se parece mucho a un documento de Excel o Google Sheets. Esto es realmente bueno para poder almacenar datos directamente dentro del tablero. Hay algunas columnas ya creadas, pero agregamos las nuestras. Aquí están las columnas que necesitamos y sus tipos:

    1. nombre (texto de una sola línea)
    2. enlace (texto de una sola línea)
    3. etiquetas (selección múltiple)
    4. comprado (casilla de verificación)

    Deberíamos agregar algunas etiquetas a la columna de etiquetas mientras estamos en ello. Agregué “nodo”, “react”, “jamstack” y “javascript” para empezar. Siéntase libre de agregar cualquier etiqueta que tenga sentido para los tipos de clases que le puedan interesar.

    También agregué algunas filas de datos en la columna de nombre según mis cursos en línea favoritos:

    1. Cree 20 aplicaciones de reaccion
    2. Patrones de seguridad avanzados de React
    3. Reaccionar y sin servidor

    Lo último que debe hacer es cambiar el nombre de la tabla. Se llama “Tabla 1” de forma predeterminada. En su lugar, le cambiaremos el nombre a “cursos”.

    Localización de credenciales de Airtable

    Antes de comenzar a escribir código, hay un par de datos que debemos obtener de Airtable. La primera es su clave API. La forma más sencilla de conseguirlo es ir a la página de su cuenta y buscar en la sección “Descripción general”.

    A continuación, necesitamos el ID de la base que acabamos de crear. Recomendaría dirigirse a la página API de Airtable porque verá una lista de sus bases. Haga clic en la base que acaba de crear y debería ver el ID de la base en la lista. La documentación de la API de Airtable es realmente útil y tiene instrucciones más detalladas para encontrar el ID de una base.

    Por último, necesitamos el nombre de la tabla. Nuevamente, llamé a los míos “cursos”, pero usa el nombre que le hayas dado al tuyo si es diferente.

    Configuración del proyecto

    Para ayudar a acelerar las cosas, creó un proyecto inicial para nosotros en el repositorio principal. Deberá hacer algunas cosas para seguir desde aquí:

    1. Bifurca el repositorio haciendo clic en el botón bifurcar
    2. Clonar el nuevo repositorio localmente
    3. Echa un vistazo a la rama inicial congit checkout starter

    Ya hay muchos archivos allí. La mayoría de los archivos provienen de una create-react-appaplicación estándar, con algunas excepciones. También hay un directorio de funciones que albergará todas nuestras funciones sin servidor. Por último, hay un netlify.tomlarchivo de configuración que le dice a Netlify dónde residen nuestras funciones sin servidor. También en esta configuración hay una redirección que simplifica la ruta que usamos para llamar a nuestras funciones. Más sobre esto pronto.

    La última parte de la configuración es incorporar variables de entorno que podemos usar en nuestras funciones sin servidor. Para hacer esto instalar el dotenvpaquete.

    npm install dotenv

    Luego, cree un .envarchivo en la raíz del repositorio con lo siguiente. Asegúrese de utilizar su propia clave API, ID base y nombre de tabla que encontró anteriormente.

    AIRTABLE_API_KEY=YOUR_API_KEYAIRTABLE_BASE_ID=YOUR_BASE_IDAIRTABLE_TABLE_NAME=YOUR_TABLE_NAME

    ¡Ahora escribamos algo de código!

    Configurar funciones sin servidor

    Para crear funciones sin servidor con Netlify, necesitamos crear un archivo JavaScript dentro de nuestro /functionsdirectorio. Ya hay algunos archivos incluidos en este directorio de inicio. Miremos courses.jsprimero el archivo.

    const  formattedReturn  =  require('./formattedReturn');const  getCourses  =  require('./getCourses');const  createCourse  =  require('./createCourse');const  deleteCourse  =  require('./deleteCourse');const  updateCourse  =  require('./updateCourse');exports.handler  =  async  (event)  =  {  return  formattedReturn(200, 'Hello World');};

    La parte central de una función sin servidor es la exports.handlerfunción. Aquí es donde manejamos la solicitud entrante y respondemos a ella. En este caso, aceptamos un parámetro de evento que usaremos en un momento.

    Estamos devolviendo una llamada dentro del controlador a la formattedReturnfunción, lo que hace que sea un poco más sencillo devolver un estado y datos del cuerpo. Así es como se ve esa función como referencia.

    module.exports  =  (statusCode, body)  =  {  return  {    statusCode,    body: JSON.stringify(body),  };};

    Observe también que estamos importando varias funciones auxiliares para manejar la interacción con Airtable. Podemos decidir a cuál de estos llamar según el método HTTP de la solicitud entrante.

    • OBTENER HTTP →getCourses
    • ENVÍO HTTP →createCourse
    • PUESTA HTTP →updateCourse
    • BORRAR HTTP →deleteCourse

    Actualicemos esta función para llamar a la función auxiliar adecuada según el método HTTP en el parámetro del evento. Si la solicitud no coincide con uno de los métodos que esperamos, podemos devolver un código de estado 405 (método no permitido).

    exports.handler = async (event) = {  if (event.httpMethod === 'GET') {    return await getCourses(event);  } else if (event.httpMethod === 'POST') {    return await createCourse(event);  } else if (event.httpMethod === 'PUT') {    return await updateCourse(event);  } else if (event.httpMethod === 'DELETE') {    return await deleteCourse(event);  } else {    return formattedReturn(405, {});  }};

    Actualizando el archivo de configuración de Airtable

    Dado que vamos a interactuar con Airtable en cada uno de los diferentes archivos auxiliares, configurémoslo una vez y reutilicémoslo. Abre el airtable.jsarchivo.

    En este archivo, queremos obtener una referencia a la coursestabla que creamos anteriormente. Para hacer eso, creamos una referencia a nuestra base Airtable usando la clave API y el ID de la base. Luego, usamos la base para obtener una referencia a la tabla y exportarla.

    require('dotenv').config();var Airtable = require('airtable');var base = new Airtable({ apiKey: process.env.AIRTABLE_API_KEY }).base(  process.env.AIRTABLE_BASE_ID);const table = base(process.env.AIRTABLE_TABLE_NAME);module.exports = { table };

    Obtener cursos

    Con la configuración de Airtable implementada, ahora podemos abrir el getCourses.jsarchivo y recuperar cursos de nuestra tabla llamando a table.select().firstPage(). La API de Airtable usa paginación, por lo que, en este caso, especificamos que queremos la primera página de registros (que son 20 registros de forma predeterminada).

    const courses = await table.select().firstPage();return formattedReturn(200, courses);

    Al igual que con cualquier llamada asíncrona/en espera, debemos manejar los errores. Rodeemos este fragmento con un intento/captura.

    try {  const courses = await table.select().firstPage();  return formattedReturn(200, courses);} catch (err) {  console.error(err);  return formattedReturn(500, {});}

    Airtable devuelve mucha información adicional en sus registros. Prefiero simplificar estos registros con solo el ID del registro y los valores para cada una de las columnas de la tabla que creamos anteriormente. Estos valores se encuentran en la fieldspropiedad. Para hacer esto, utilicé un mapa de matriz para formatear los datos como quiero.

    const { table } = require('./airtable');const formattedReturn = require('./formattedReturn');module.exports = async (event) = {  try {    const courses = await table.select().firstPage();    const formattedCourses = courses.map((course) = ({      id: course.id,      ...course.fields,    }));    return formattedReturn(200, formattedCourses);  } catch (err) {    console.error(err);    return formattedReturn(500, {});  }};

    ¿Cómo probamos esto? Bueno, netlify-clinos proporciona un netlify devcomando para ejecutar nuestras funciones sin servidor (y nuestro front-end) localmente. Primero, instale la CLI:

    npm install -g netlify-cli

    Luego, ejecute el netlify devcomando dentro del directorio.

    Este hermoso comando hace algunas cosas por nosotros:

    • Ejecuta las funciones sin servidor.
    • Ejecuta un servidor web para su sitio
    • Crea un proxy para que las funciones front-end y sin servidor se comuniquen entre sí en el puerto 8888.

    Abramos la siguiente URL para ver si esto funciona:

    Podemos usarlo /api/*para nuestra API debido a la configuración de redireccionamiento en el netlify.tomlarchivo.

    Si tiene éxito, deberíamos ver nuestros datos mostrados en el navegador.

    Creando cursos

    Agreguemos la funcionalidad para crear un curso abriendo el createCourse.jsarchivo. Necesitamos tomar las propiedades del cuerpo POST entrante y usarlas para crear un nuevo registro llamando a table.create().

    El entrante event.bodyviene en una cadena normal, lo que significa que debemos analizarlo para obtener un objeto JavaScript.

    const fields = JSON.parse(event.body);

    Luego, usamos esos campos para crear un nuevo curso. Observe que la create()función acepta una matriz que nos permite crear múltiples registros a la vez.

    const createdCourse = await table.create([{ fields }]);

    Entonces, podemos devolver el createdCourse:

    return formattedReturn(200, createdCourse);

    Y, por supuesto, deberíamos terminar todo con un try/catch:

    const { table } = require('./airtable');const formattedReturn = require('./formattedReturn');module.exports = async (event) = {  const fields = JSON.parse(event.body);  try {    const createdCourse = await table.create([{ fields }]);    return formattedReturn(200, createdCourse);  } catch (err) {    console.error(err);    return formattedReturn(500, {});  }};

    Dado que no podemos realizar POST, PUT o DELETE directamente en la dirección web del navegador (como hicimos para GET), necesitamos usar una herramienta separada para probar nuestros puntos finales de ahora en adelante. Prefiero Postman, pero también he oído cosas buenas sobre Insomnia.

    Dentro de Postman, necesito la siguiente configuración.

    • url: localhost:8888/api/cursos
    • method: CORREO
    • body: objeto JSON con name, linkytags

    Después de ejecutar la solicitud, deberíamos ver que se devuelve el nuevo registro del curso.

    También podemos consultar la GUI de Airtable para ver el nuevo registro.

    Consejo: Copie y pegue el ID del nuevo registro para usarlo en las siguientes dos funciones.

    Actualización de cursos

    Ahora, pasemos a actualizar un curso existente. Del cuerpo de la solicitud entrante, necesitamos el idregistro así como los otros valores de campo.

    Podemos capturar específicamente el valor de id usando la desestructuración de objetos, así:

    const {id} = JSON.parse(event.body);

    Luego, podemos usar el operador de extensión para tomar el resto de los valores y asignarlos a una variable llamada fields:

    const {id, ...fields} = JSON.parse(event.body);

    Desde allí, llamamos a la update()función que toma una matriz de objetos (cada uno con una propiedad idy fields) para actualizar:

    const updatedCourse = await table.update([{id, fields}]);

    Aquí está el archivo completo con todo eso junto:

    const { table } = require('./airtable');const formattedReturn = require('./formattedReturn');module.exports = async (event) = {  const { id, ...fields } = JSON.parse(event.body);  try {    const updatedCourse = await table.update([{ id, fields }]);    return formattedReturn(200, updatedCourse);  } catch (err) {    console.error(err);    return formattedReturn(500, {});  }};

    Para probar esto, recurriremos a Postman para la solicitud PUT:

    • url: localhost:8888/api/cursos
    • method: PONER
    • body: objeto JSON con id(el iddel curso que acabamos de crear) y los campos que queremos actualizar ( name, linky tags)

    Decidí agregar "¡¡¡Actualizado!!!" al nombre de un curso una vez que se ha actualizado.

    También podemos ver el cambio en la GUI de Airtable.

    Eliminar cursos

    Por último, necesitamos agregar la funcionalidad de eliminación. Abre el deleteCourse.jsarchivo. Necesitaremos obtener la identificación del cuerpo de la solicitud y usarla para llamar a la destroy()función.

    const { id } = JSON.parse(event.body);const deletedCourse = await table.destroy(id);

    El archivo final se ve así:

    const { table } = require('./airtable');const formattedReturn = require('./formattedReturn');module.exports = async (event) = {  const { id } = JSON.parse(event.body);  try {    const deletedCourse = await table.destroy(id);    return formattedReturn(200, deletedCourse);  } catch (err) {    console.error(err);    return formattedReturn(500, {});  }};

    Aquí está la configuración para la solicitud de eliminación en Postman.

    • url: localhost:8888/api/cursos
    • method: BORRAR
    • body: Objeto JSON con una identificación (la misma identificación del curso que acabamos de actualizar)

    Y, por supuesto, podemos verificar que el registro se eliminó mirando la GUI de Airtable.

    Mostrando una lista de cursos en React

    ¡Vaya, hemos construido todo nuestro back-end! Ahora, pasemos al frente. La mayor parte del código ya está escrito. Solo necesitamos escribir las partes que interactúan con nuestras funciones sin servidor. Comencemos mostrando una lista de cursos.

    Abra el App.jsarchivo y busque la loadCoursesfunción. En el interior, debemos realizar una llamada a nuestra función sin servidor para recuperar la lista de cursos. Para esta aplicación, realizaremos una solicitud HTTP utilizando fetch, que está integrado.

    Gracias al netlify devcomando, podemos realizar nuestra solicitud utilizando una ruta relativa al punto final. ¡Lo bueno es que esto significa que no necesitamos realizar ningún cambio después de implementar nuestra aplicación!

    const res = await fetch('/api/courses');const courses = await res.json();

    Luego, almacene la lista de cursos en la coursesvariable de estado.

    setCourses(courses)

    Júntalo todo y envuélvelo con un try/catch:

    const loadCourses = async () = {  try {    const res = await fetch('/api/courses');    const courses = await res.json();    setCourses(courses);  } catch (error) {    console.error(error);  }};

    Abrimos localhost:8888en el navegador y deberíamos ver nuestra lista de cursos.

    Agregar cursos en React

    Ahora que tenemos la capacidad de ver nuestros cursos, necesitamos la funcionalidad para crear nuevos cursos. Abra el CourseForm.jsarchivo y busque la submitCoursefunción. Aquí, necesitaremos realizar una solicitud POST a la API y enviar las entradas desde el formulario en el cuerpo.

    La API JavaScript Fetch realiza solicitudes GET de forma predeterminada, por lo que para enviar una POST, debemos pasar un objeto de configuración con la solicitud. Este optionsobjeto tendrá estas dos propiedades.

    1. method→ PUBLICAR
    2. body→ una versión en cadena de los datos de entrada
    await fetch('/api/courses', {  method: 'POST',  body: JSON.stringify({    name,    link,    tags,  }),});

    Luego, rodee la llamada con try/catch y la función completa se verá así:

    const submitCourse = async (e) = {  e.preventDefault();  try {    await fetch('/api/courses', {      method: 'POST',      body: JSON.stringify({        name,        link,        tags,      }),    });    resetForm();    courseAdded();  } catch (err) {    console.error(err);  }};

    Pruebe esto en el navegador. Rellena el formulario y envíalo.

    Después de enviar el formulario, éste debe restablecerse y la lista de cursos debe actualizarse con el curso recién agregado.

    Actualización de cursos comprados en React

    La lista de cursos se divide en dos secciones diferentes: una con cursos que se han comprado y otra con cursos que no se han comprado. Podemos agregar la funcionalidad para marcar un curso como "comprado" para que aparezca en la sección derecha. Para hacer esto, enviaremos una solicitud PUT a la API.

    Abra el Course.jsarchivo y busque la markCoursePurchasedfunción. Aquí, realizaremos la solicitud PUT e incluiremos tanto la identificación del curso como las propiedades del curso con la propiedad comprada configurada como verdadera. Podemos hacer esto pasando todas las propiedades del curso con el operador de extensión y luego anulando la purchasedpropiedad para que sea verdadera.

    const markCoursePurchased = async () = {  try {    await fetch('/api/courses', {      method: 'PUT',      body: JSON.stringify({ ...course, purchased: true }),    });    refreshCourses();  } catch (err) {    console.error(err);  }};

    Para probar esto, haga clic en el botón para marcar uno de los cursos como comprado y la lista de cursos debería actualizarse para mostrar el curso en la sección comprado.

    Eliminar cursos en React

    Y, siguiendo con nuestro modelo CRUD, agregaremos la posibilidad de eliminar cursos. Para hacer esto, ubique la función eliminarCurso en el Course.jsarchivo que acabamos de editar. Necesitaremos realizar una solicitud DELETE a la API y pasar la identificación del curso que queremos eliminar.

    const deleteCourse = async () = {  try {    await fetch('/api/courses', {      method: 'DELETE',      body: JSON.stringify({ id: course.id }),    });    refreshCourses();  } catch (err) {    console.error(err);  }};

    Para probar esto, haga clic en el botón "Eliminar" al lado del curso y el curso debería desaparecer de la lista. También podemos verificar que haya desaparecido por completo revisando el panel de Airtable.

    Implementación en Netlify

    Ahora que tenemos toda la funcionalidad CRUD que necesitamos en el front-end y back-end, es hora de implementar esto en Netlify. Con suerte, estás tan entusiasmado como yo por lo fácil que es ahora. Solo asegúrese de que todo esté enviado a GitHub antes de pasar a la implementación.

    Si no tiene una cuenta de Netlify, deberá crear una (como Airtable, es gratis). Luego, en el panel, haga clic en la opción "Nuevo sitio desde Git". Seleccione GitHub, autentíquelo y luego seleccione el repositorio del proyecto.

    A continuación, debemos decirle a Netlify desde qué rama implementar. Tenemos dos opciones aquí.

    1. Utilice la startersucursal en la que hemos estado trabajando.
    2. Elija la rama maestra con la versión final del código.

    Por ahora, elegiría la starterrama para asegurarme de que el código funcione. Luego, debemos elegir un comando que cree la aplicación y el directorio de publicación que la sirve.

    1. Comando de compilación:npm run build
    2. Directorio de publicación:build

    Netlify envió recientemente una actualización que trata las advertencias de React como errores durante el proceso de compilación. lo que puede hacer que la compilación falle. He actualizado el comando de compilación para CI = npm run buildtener en cuenta esto.

    Por último, haga clic en el botón "Mostrar avanzado" y agregue las variables de entorno. Estos deberían ser exactamente como estaban en el local .envque creamos.

    El sitio debería comenzar a construirse automáticamente.

    Podemos hacer clic en la pestaña "Implementar" en la pestaña Netlify y realizar un seguimiento del progreso de la compilación, aunque va bastante rápido. Cuando esté completo, ¡nuestra nueva y brillante aplicación se implementará para que todo el mundo pueda verla!

    ¡Bienvenido a Jamstack!

    Jamstack es un lugar nuevo y divertido para estar. Me encanta porque hace que crear y alojar aplicaciones completas y completamente funcionales como esta sea bastante trivial. ¡Me encanta que Jamstack nos convierta en desarrolladores front-end poderosos y todopoderosos!

    Espero que vea el mismo poder y facilidad con la combinación de tecnología que utilizamos aquí. Nuevamente, Jamstack no requiere que usemos Airtable, React o Netlify, pero podemos, y todos están disponibles gratuitamente y son fáciles de configurar. Visite el sitio sin servidor de Chris para conocer una gran cantidad de otros servicios, recursos e ideas para trabajar en Jamstack. ¡Y no dudes en dejar preguntas y comentarios en los comentarios aquí!

    SUSCRÍBETE A NUESTRO BOLETÍN 
    No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.

    Deja un comentario

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

    Subir

    Este sitio web utiliza cookies para mejorar tu experiencia mientras navegas por él. Este sitio web utiliza cookies para mejorar tu experiencia de usuario. Al continuar navegando, aceptas su uso. Mas informacion