paint-brush
Un nuevo truco de interfaz está mejorando el rendimiento de la APIpor@axotion
Nueva Historia

Un nuevo truco de interfaz está mejorando el rendimiento de la API

por Kamil Fronczak4m2025/01/17
Read on Terminal Reader

Demasiado Largo; Para Leer

En el pasado, los desarrolladores usaban la misma API para lecturas y escrituras en todos los casos. Esto generaba dificultades para optimizar los índices en campos que recibían muchas consultas. El patrón de clave Valet, CQRS y las bases de datos de búsqueda cambiaron eso.
featured image - Un nuevo truco de interfaz está mejorando el rendimiento de la API
Kamil Fronczak HackerNoon profile picture
0-item

En el pasado, solía observar un enfoque común en el que los desarrolladores (incluido yo mismo, por supuesto) utilizaban la misma API tanto para las lecturas como para las escrituras en todos los casos. Más aún, con frecuencia dependíamos de la misma fuente de datos, como MySQL/PostgreSQL, para gestionar ambas operaciones.


Esto significa escribir en las mismas columnas y leer desde ellas, lo que a menudo genera dificultades para optimizar los índices en campos que fueron consultados intensamente.


Por ejemplo, frecuentemente nos encontrábamos modificando índices para acomodar nuevos filtros o mejorar el rendimiento de las consultas, y los campos utilizados con operadores como LIKE planteaban desafíos particulares debido a su impacto en el rendimiento.


Estos cambios a menudo conducen a ajustes adicionales en el backend, incluida la modificación de las API para exponer la funcionalidad actualizada, tiempos medidos debido a JOIN adicionales, etc.


Descripción de la imagen

Para abordar el desafío de agregar nuevos filtros y cosas en la API, hubo intentos de optimizar el proceso utilizando herramientas y estándares como Apicalypse y, por supuesto, GraphQL .


Estas soluciones tenían como objetivo agilizar la generación de consultas API y reducir el esfuerzo manual necesario para implementar nuevos filtros y funcionalidades, ofreciendo un enfoque más dinámico para gestionar el acceso a los datos, pero tenían una curva de aprendizaje alta.


Descripción de la imagen


Con el auge de CQRS (Command Query Responsibility Segregation), comenzó a surgir un nuevo enfoque. Esta mentalidad fomentaba el uso de fuentes separadas para escrituras y lecturas. Las escrituras podían emitir eventos y las lecturas podían crear vistas a partir de esos eventos en lugares dedicados. Incluso si las lecturas y escrituras se administraban dentro de la misma base de datos (pero en tablas diferentes), esta separación trajo consigo beneficios significativos y, por supuesto, permitió deshacerse del segundo desafío: las uniones y las consultas de búsqueda en modelos de dominio, ya que los modelos de lectura suelen tener la forma de JSON desnormalizados.


Descripción de la imagen

Sin embargo, esto generó otro problema. Con las lecturas, teníamos que escalar las escrituras, lo que significa que la única razón por la que teníamos que escalar las instancias de nuestra aplicación de X a Y era debido a las lecturas. Este problema se podría mitigar parcialmente con el almacenamiento en caché y, en el mundo de los microservicios, podríamos tener microservicios dedicados para las lecturas.


Pero...


Aun así, esta no era una solución ideal para otros estilos arquitectónicos como los monolitos modulares, donde tal separación podría no alinearse bien con la filosofía de diseño del sistema. Otra cosa era que, cuando la API no funcionaba, todo el producto no funcionaba y, teniendo en cuenta que la mayoría de los productos dependen más de las lecturas que de las escrituras, podría tener un impacto innecesario en el negocio (por supuesto, una separación de la API no funciona ;) )


Entonces, ¿qué sucedería si pudiéramos solicitar esas "vistas", también conocidas como modelos de lectura, directamente sin involucrar a la API ni manejar cargas? Aquí es donde entran en juego soluciones como Meilisearch , AppSearch y otras, que aprovechan un patrón llamado "Valet Key". Al usar este patrón, los frontends pueden acceder directamente a los modelos optimizados para lectura, lo que reduce la dependencia de las API del backend. Por supuesto, el frontend aún tiene que "pedirle" a la API la "Valet key", pero puede almacenar claves en caché, por lo que incluso cuando la API está inactiva, el frontend aún puede comunicarse y mostrar contenido.


Descripción de la imagen

Descripción de la imagen


Con este enfoque, podemos centrarnos en la base de datos de lectura y no preocuparnos por gestionar el tráfico de lecturas en nuestra API. La "clave de valet" proporcionada al frontend a través de nuestra API está protegida de forma que el frontend no puede modificarla. Incluye filtros e índices predefinidos.


Si el frontend requiere capacidades adicionales, puede solicitarlas a través de la API, donde la API puede validar si se permiten o no. Siguen siendo menos llamadas.


Algunas ventajas que puedo ver son:

  • Carga de API reducida : descarga el tráfico de lectura de la API, lo que le permite centrarse en las operaciones principales.
  • Escalabilidad : las bases de datos de lectura o los servicios de búsqueda están mejor optimizados para manejar alto tráfico, lo que reduce la necesidad de escalar el backend de la aplicación.
  • Flexibilidad : las opciones SaaS o autohospedadas permiten a los equipos elegir la opción que mejor se adapte a su infraestructura.
  • Seguridad : los filtros e índices predefinidos garantizan que el frontend solo pueda acceder a los datos permitidos, lo que minimiza los riesgos. La API puede invalidar las claves.
  • Eficiencia del desarrollador : reduce la necesidad de actualizaciones constantes de API para nuevos filtros o capacidades de búsqueda.
  • Rendimiento mejorado : el acceso directo a modelos optimizados para lectura proporciona respuestas de consultas más rápidas para los usuarios.


Pero siempre hay contras:

  • Consistencia eventual : los datos pueden aparecer después de algún tiempo debido a la naturaleza de la consistencia eventual en los modelos de lectura.
  • Mantenimiento adicional: introduce un componente adicional que requiere monitoreo y gestión.
  • Complejidad del esquema : los esquemas deben almacenarse en código o en un lugar común, ya que diferentes equipos de diferentes contextos pueden necesitar completar el mismo documento (por ejemplo, empleado con correo electrónico, pero también con créditos y cupones disponibles). Si bien no está directamente relacionado con este patrón, agrega complejidad.
  • Costo de la versión SaaS o mantenimiento autoalojado


Entonces, este enfoque no es una solución milagrosa e introduce su propio conjunto de desafíos, pero si no le molestan las desventajas, entonces un pequeño cambio en el frontend probablemente no requerirá involucrar al equipo backend, agilizando el proceso de desarrollo y mejorando la agilidad general y, por supuesto, la escalabilidad debería ser más fácil.