Funciones sin servidor: el secreto para equipos front-end ultraproductivos

Las aplicaciones modernas imponen grandes exigencias a los desarrolladores de aplicaciones para el usuario. Las aplicaciones web requieren una funcionalidad compleja, y la mayor parte de ese trabajo recae en los desarrolladores de aplicaciones para el usuario:

  • Construyendo interfaces de usuario modernas y accesibles.
  • crear elementos interactivos y animaciones complejas
  • gestionar el estado de aplicaciones complejas
  • Metaprogramación: creación de scripts, transpiladores, agrupadores, linters, etc.
  • lectura de REST, GraphQL y otras API
  • Programación de nivel medio: proxies, redirecciones, enrutamiento, middleware, autenticación, etc.

Esta lista es desalentadora por sí sola, pero se vuelve muy difícil si su pila tecnológica no se optimiza para lograr simplicidad. Una infraestructura compleja introduce responsabilidades ocultas que generan riesgos, desaceleraciones y frustración.

Dependiendo de la infraestructura que elijamos, también podemos agregar sin darnos cuenta la configuración del servidor, la administración de lanzamientos y otras tareas de DevOps a la tarea de un desarrollador front-end.

La arquitectura de software tiene un impacto directo en la productividad del equipo. Elija herramientas que eviten la complejidad oculta para ayudar a sus equipos a lograr más y sentirse menos sobrecargados.

El astuto nivel medio, donde las tareas de front-end pueden aumentar en complejidad

Veamos una tarea que he visto asignada a varios equipos de front-end: crear una API REST simple para combinar datos de algunos servicios en una sola solicitud para el front-end. Si acaba de gritarle a su computadora: “¡Pero esa no es una tarea de interfaz!” – ¡Estoy de acuerdo! ¿Pero quién soy yo para permitir que los hechos obstaculicen el trabajo atrasado?

Una API que solo es necesaria para la interfaz entra en la programación de nivel medio . Por ejemplo, si el front-end combina los datos de varios servicios backend y deriva algunos campos adicionales, un enfoque común es agregar una API proxy para que el front-end no realice múltiples llamadas a la API ni aplique un montón de lógica de negocios en el cliente. lado.

No hay una línea clara sobre qué equipo de back-end debería poseer una API como esta. Incluirlo en el trabajo pendiente de otro equipo (y obtener actualizaciones en el futuro) puede ser una pesadilla burocrática, por lo que el equipo de front-end termina con la responsabilidad.

Esta es una historia que termina de manera diferente según las elecciones arquitectónicas que hagamos. Veamos dos enfoques comunes para manejar esta tarea:

  • Cree una aplicación Express en Node para crear la API REST
  • Utilice funciones sin servidor para crear la API REST

Express + Node viene con una sorprendente cantidad de complejidad oculta y gastos generales. Serverless permite a los desarrolladores de front-end implementar y escalar la API rápidamente para que puedan volver a sus otras tareas de front-end.

Solución 1: cree e implemente la API utilizando Node y Express (y Docker y Kubernetes)

Al principio de mi carrera, el procedimiento operativo estándar era utilizar Node y Express para implementar una API REST. A primera vista, esto parece relativamente sencillo. Podemos crear toda la API REST en un archivo llamado server.js:

const express = require('express');const PORT = 8080;const HOST = '0.0.0.0';const app = express();app.use(express.static('site'));// simple REST API to load movies by slugconst movies = require('./data.json');app.get('/api/movies/:slug', (req, res) = {  const { slug } = req.params;  const movie = movies.find((m) = m.slug === slug);  res.json(movie);});app.listen(PORT, HOST, () = {  console.log(`app running on http://${HOST}:${PORT}`);});

Este código no está muy alejado del JavaScript front-end. Hay una cantidad decente de texto repetitivo aquí que hará tropezar a un desarrollador front-end si nunca lo ha visto antes, pero es manejable.

Si ejecutamos node server.js, podemos visitar http://localhost:8080/api/movies/some-moviey ver un objeto JSON con detalles de la película con el slug some-movie(suponiendo que lo hayas definido en data.json).

La implementación introduce una gran cantidad de gastos generales adicionales

Sin embargo, crear la API es sólo el comienzo. Necesitamos implementar esta API de manera que pueda manejar una cantidad decente de tráfico sin fallar. De repente, las cosas se complican mucho más.

Necesitamos varias herramientas más:

  • algún lugar para implementar esto (por ejemplo, DigitalOcean, Google Cloud Platform, AWS)
  • un contenedor para mantener la coherencia entre el desarrollo y la producción local (es decir, Docker)
  • una forma de garantizar que la implementación se mantenga activa y pueda manejar picos de tráfico (es decir, Kubernetes)

En este punto, estamos muy fuera del territorio del front-end. He hecho este tipo de trabajo antes, pero mi solución fue copiar y pegar desde un tutorial o una respuesta de Stack Overflow.

La configuración de Docker es algo comprensible, pero no tengo idea si es segura u optimizada:

FROM node:14WORKDIR /usr/src/appCOPY package*.json ./RUN npm installCOPY . .EXPOSE 8080CMD [ "node", "server.js" ]

A continuación, debemos descubrir cómo implementar el contenedor Docker en Kubernetes. ¿Por qué? No estoy muy seguro, pero eso es lo que usan los equipos de back-end de la empresa, por lo que debemos seguir las mejores prácticas.

Esto requiere más configuración (todo copiado y pegado). Confiamos nuestro destino a Google y elaboramos las instrucciones de Docker para implementar un contenedor en Kubernetes .

Nuestra tarea inicial de “crear una API de nodo rápida” se ha convertido en un conjunto de tareas que no se alinean con nuestro conjunto de habilidades principales. La primera vez que me asignaron una tarea como esta, perdí varios días configurando las cosas y esperando comentarios de los equipos de backend para asegurarme de no estar causando más problemas de los que estaba resolviendo.

Algunas empresas cuentan con un equipo de DevOps para comprobar este trabajo y asegurarse de que no haga nada terrible. Otros terminan confiando en la mente colmena de Stack Overflow y esperando lo mejor.

Con este enfoque, las cosas comienzan siendo manejables con algo de código de Nodo, pero rápidamente se convierten en múltiples capas de configuración que abarcan áreas de especialización que van mucho más allá de lo que deberíamos esperar que sepa un desarrollador frontend.

Solución 2: cree la misma API REST utilizando funciones sin servidor

Si elegimos funciones sin servidor, la historia puede ser dramáticamente diferente. Serverless es un gran complemento para las aplicaciones web Jamstack que brinda a los desarrolladores front-end la capacidad de manejar la programación de nivel medio sin la complejidad innecesaria de descubrir cómo implementar y escalar un servidor.

Existen múltiples marcos y plataformas que hacen que la implementación de funciones sin servidor sea sencilla. Mi solución preferida es utilizar Netlify, ya que permite la entrega continua automatizada de funciones front-end y sin servidor. Para este ejemplo, usaremos Netlify Functions para administrar nuestra API sin servidor.

Usar funciones como servicio (una forma elegante de describir plataformas que manejan la infraestructura y escalan para funciones sin servidor) significa que podemos centrarnos solo en la lógica empresarial y saber que nuestro servicio de nivel medio puede manejar grandes cantidades de tráfico sin fallar. No necesitamos lidiar con contenedores Docker o Kubernetes o incluso con el modelo estándar de un servidor Node: simplemente funciona™ para que podamos enviar una solución y pasar a nuestra siguiente tarea.

Primero, podemos definir nuestra API REST en una función sin servidor en netlify/functions/movie-by-slug.js:

const movies = require('./data.json');exports.handler = async (event) = {  const slug = event.path.replace('/api/movies/', '');  const movie = movies.find((m) = m.slug === slug);  return {    statusCode: 200,    body: JSON.stringify(movie),  };};

Para agregar el enrutamiento adecuado, podemos crear un netlify.tomlen la raíz del proyecto:

[[redirects]]  from = "/api/movies/*"  to = "/.netlify/functions/movie-by-slug"  status = 200

Esta es una configuración significativamente menor de la que necesitaríamos para el enfoque Node/Express. Lo que prefiero de este enfoque es que la configuración aquí se reduzca a lo que nos interesa: las rutas específicas que nuestra API debe manejar. El resto (comandos de creación, puertos, etc.) lo manejamos con buenos valores predeterminados.

Si tenemos instalada la CLI de Netlify , podemos ejecutarla localmente de inmediato con el comando ntl dev, que sabe buscar funciones sin servidor en el netlify/functionsdirectorio.

La visita http://localhost:888/api/movies/boopermostrará un objeto JSON que contiene detalles sobre la película “booper”.

Hasta ahora, esto no parece muy diferente de la configuración de Node y Express. Sin embargo, cuando vamos a implementar, la diferencia es enorme . Esto es lo que se necesita para implementar este sitio en producción:

  1. Confirme la función sin servidor, netlify.tomlrealice un repositorio y publíquela en GitHub, Bitbucket o GitLab.
  2. Utilice la CLI de Netlify para crear un nuevo sitio conectado a su repositorio de git:ntl init

¡Eso es todo! La API ahora está implementada y es capaz de escalar según demanda a millones de visitas. Los cambios se implementarán automáticamente cada vez que se envíen a la rama principal del repositorio.

Puede ver esto en acción en https://serverless-rest-api.netlify.app y consultar el código fuente en GitHub .

La tecnología sin servidor abre un enorme potencial para los desarrolladores front-end

Las funciones sin servidor no reemplazan todos los back-ends, pero son una opción extremadamente poderosa para manejar el desarrollo de nivel medio. La tecnología sin servidor evita la complejidad involuntaria que puede provocar cuellos de botella organizativos y graves problemas de eficiencia.

El uso de funciones sin servidor permite a los desarrolladores front-end completar tareas de programación de nivel medio sin asumir la sobrecarga adicional de DevOps que genera riesgos y disminuye la productividad.

Si nuestro objetivo es capacitar a los equipos frontend para que envíen software de forma rápida y segura, elegir funciones sin servidor incorpora productividad a la infraestructura. Desde que adopté este enfoque como mi iniciador predeterminado de Jamstack, he podido realizar envíos más rápido que nunca, ya sea trabajando solo, con otros desarrolladores de front-end o de forma multifuncional con equipos de una empresa.

Deja un comentario

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

Subir