Frontend en Lyft: Un panorama

En Lyft tenemos el enorme privilegio de trabajar con un producto que beneficia a millones de personas en los Estados Unidos y Canadá. Mucha gente conoce a Lyft mediante nuestras apps, que son la principal forma en la que nuestros usuarios otorgan o piden viajes, rentan un vehículo o utilizan nuestras bicicletas y scooters. De la infraestructura que lo hace posible, la mayor parte está conformada por miles de microservicios de backend. Sin embargo, ¿sabías que también realizamos una buena cantidad de desarrollo frontend de web?

Aunque puede ser motivo de sorpresa, el desarrollo frontend es parte integral de lo que hace posible a Lyft. La mayoría de nuestros microservicios de frontend están construidos sobre un stack basado en Typescript; estos servicios hacen cosas como:

  • sostener a lyft.com y otros sitios web afiliados,
  • proporcionar servicios a nuestros socios corporativos permitiéndoles manejar sus flotillas dentro de la red de Lyft (como con nuestro convenio con Hertz, gracias al cual es posible rentar un auto para manejar con Lyft),
  • permitir la administración de recursos internos mediante interfaces fáciles de usar, las que dan más confiabilidad a nuestras operaciones,
  • dar a nuestros científicos la capacidad de entender y mejorar cómo está operando Lyft mediante herramientas de datos,
  • mostrar tableros de datos con experiencias de usuario e interfaces diseñadas para actividades como monitoreo de indicadores, búsqueda y toma de decisiones.

Todo lo anterior requiere un alto nivel de calidad. El desarrollo de software frontend es un complejo espacio de soluciones, en el que varios factores deben entrar en consideración, entre ellos: escalabilidad, resistencia a fallos, experiencias de usuario consistentes y clientes con capacidades heterogéneas; todo con código que pueda correr tanto en ambientes de cliente como servidor. Lograr estos objetivos proporcionará a nuestros conductores y pasajeros con las mejores experiencias de transporte.

Herramientas e infraestructura

Para que nuestros procesos de desarrollo de software fueran confiables y rápidos, al tiempo que la experiencia del desarrollador fuera excelente, invertimos tempranamente en herramientas e infraestructura.

Cuando entré a Lyft, a mediados del 2016, no éramos más de 25 ingenieros de frontend. Nuestra infraestructura en ese entonces era sencilla; ya se hacía evidente que debía volverse más escalable. De ahí que comenzamos a migrar nuestras herramientas de un esquema monolítico basado en Angular a una red verdaderamente distribuida de servicios React-sobre-Node para hospedarlas.

Antes: un monolito de frontend se comunicaba con muchos servicios de backend.

La transición de tener docenas a cientos de microservicios fue posible gracias al uso de bibliotecas compartidas y centralizadas, como nuestro sistema de configuración y compilación, llamado Frontend Build. Este sistema nos permitió crear nuevos servicios desde cero sobre Express, con configuraciones por defecto para Webpack, y conectados a la malla de microservicios de Lyft mediante Envoy. Esto también nos permitió dar mejor soporte a tecnologías y estándares recomendados, tales como Redux para administrar estado y Jest para pruebas.

Después: si bien la correspondencia no es necesariamente 1:1, los servicios de frontend ahora están mucho mejor distribuidos.

Otra pieza de código compartida, en este caso para estilos, fue un conjunto de clases que seguían la filosofía de css atómico; esto permitió a cualquier desarrollador crear interfaces "al estilo Lyft" usando dichas clases, que estaban bien documentadas.

En este tiempo también se creó un portal interno para compartir componentes de React usando lerna y storybook. Los componentes ahí se convierte en su propio paquete dentro de un namespace interno; esto hace que importarlos en otros proyectos de frontend dentro de Lyft sea trivialmente fácil.

La tecnología de desarrollo frontend siguió evolucionando y Frontend Build le siguió los pasos. Por ejemplo, cuando llegó el momento adecuado, dejamos de promover Redux; en su lugar comenzamos a aconsejar el uso de React Context. No obstante esta promoción, los desarrolladores y los equipos, a fin de cuentas, seguían siendo los verdaderos dueños de los servicios que creaban (de los cuales había cada vez más). Gracias a esto, la experiencia del usuario podía ser ajustada de la mejor manera para cada caso particular, ya fuera para exploración de datos, su visualización, o para el servicio de soporte a nuestros conductores y pasajeros mediante flujos de usuario específicos.

Una vista muy simplificada de la evolución de la plataforma de frontend en Lyft.

Tan solo cuatro años después, ya somos casi cien desarrolladores frontend, distribuidos en seis oficinas y dos continentes. El esquema distribuido funciona bien para Lyft, aunque también ha introducido algunos retos. Por ejemplo, dado que cada equipo es responsable de sus propios servicios, estos tienden a divergir grandemente en cuestión de tecnologías. Debido a esto, llegamos a un punto en el que actualizar Frontend Build dentro de un servicio era una tarea compleja y, a veces, extremadamente difícil — y no hacerlo podía exponernos a un gran número de problemas, inclusive a riesgos de seguridad. Era tiempo de un cambio, uno que nos permitiera dar soporte a un gran número de casos de uso, facilitar las actualizaciones, y al mismo tiempo seguir poniendo a los desarrolladores al mando de sus propios productos.

La solución llegó en el 2020 con @lyft/service, una nueva plataforma de infraestructura basada en Next.js. Al adoptar Next.js, la infraestructura se puede actualizar automáticamente en casi todos los casos, pero los desarrolladores y equipos mantienen el control de la configuración: la mayoría de las integraciones específicas de Lyft han migrado a un sistema de plugins, pero los paquetes externos aún son bienvenidos. (Para aprender más sobre cómo logramos esta migración, puedes leer “Changing Lanes: How Lyft is Migrating 100+ Frontend Microservices to Next.js”, en inglés.)

Mientras tanto, nuestros amigos en la organización de Diseño, quienes enfrentaban retos similares, crearon el sistema de diseño llamado Lenguaje de Producto de Lyft (LPL, Lyft Product Language), que otorga consistencia visual a todas nuestras apps, tanto en plataformas móviles como en web. Junto con esto, en 2019 se creó la primera versión de LPL para frontend, en la forma de una biblioteca llamada Core UI; ésta ha reemplazado nuestras viejas clases atómicas. Al ser un puerto, CoreUI hace de la implementación de interfaces un asunto sencillo, pues se basa en el mismo lenguaje visual en el que se hacen los diseños. Además, CoreUI usa styled components ("componentes de estilo") para empotrar CSS, brindando mejor modularidad y menores tamaños de bundle. CoreUI incluye, por ejemplo, tipografía, colores, entradas de datos, botones, selectores, íconos y componentes de diseño de página.

CoreUI también está hospedado internamente usando Storyboard.

Hoy en día, en el ecosistema de Lyft existen casi cien diferentes microservicios específicos de frontend, administrados por una variedad de equipos.

Organización y comunicación

Los equipos de ingeniería en Lyft están integrados verticalmente. En vez de tener equipos divididos por función laboral (por ejemplo, un equipo de Frontend, uno de Backend…), cada equipo se encarga de una parte del producto de Lyft.

Por ejemplo, mi equipo se llama Pricing; nos hacemos responsables de proporcionar precios adecuados para todos los viajes, así como de los algoritmos que lo hacen posible. Este es un esfuerzo multidisciplinario, del cual yo, como desarrollador frontend, también soy parte.

En este estilo de organización, el contacto efectivo con otros desarrolladores frontend puede ser un reto. Necesitamos de esa colaboración para lo más básico de nuestro trabajo: por ejemplo, cada pull request debe ser revisado por otro desarrollador frontend. En mi caso, al ser el único en mi equipo, esto me empuja a construir relaciones con otros equipos.

Los miembros de Frontend estamos distribuidos a través de varios equipos.

Por tal motivo, como organización distribuida, Frontend en Lyft pone un énfasis especial en crear comunidad y permitir la comunicación. Estas son algunas de las maneras en las que lo hacemos:

  • Tenemos varios eventos abiertos a toda la organización de Frontend, como una junta general mensual ("All-Hands"), donde todos — desde los miembros más expertos hasta los más recientes — están invitados a compartir lo que deseen.
  • Tenemos un calendario compartido de actividades que todos los que hacemos trabajo de frontend podemos revisar.
  • Hay un canal de Slack #frontend para preguntas generales, así como un número de canales especializados en ciertos tópicos. Slack es un excelente medio para obtener apoyo rápido, solicitar revisiones, consultar soluciones a problemas que otros han enfrentado antes, etcétera.
  • También organizamos eventos informales, como un convivio mensual llamado "Frontend y Amigos" (Frontend and Friends), con el solo propósito de conectarnos entre nosotros.
  • La organización de Frontend también comenzó su propio programa de mentores, el que ha ayudado grandemente a reducir el aislamiento y ha permitido que los individuos se apoyen unos a otros, técnica y profesionalmente. Este programa ha crecido recientemente para abarcar a todo Ingeniería.
  • Existe también un portal interno que documenta todos los estándares generalmente aceptados en Lyft. Otro portal lista todos los servicios de frontend y cómo se ajustan a los diversos estándares.

Al centro de todo está nuestro Grupo de Trabajo de Frontend (Frontend Working Group), un organismo de voluntarios que coordina el trabajo para estandarizar y avanzar nuestras tecnologías y estándares internos, gestionar el crecimiento y el desarrollo laboral de los ingenieros de frontend, y asegurar que seamos realmente una comunidad — un desafío especialmente duro durante la pandemia de COVID.

El Grupo de Trabajo de Frontend tiene promotores ejecutivos y representantes de todas las líneas de negocio de Lyft. Consiste de un grupo central y tres subgrupos (grouplets): Tecnología, Carrera y Comunidad; cada subgrupo trabaja en sus propios temas de manera independiente. El subgrupo de Tecnología lidia con tópicos como: accesibilidad, manejo de estados, rendimiento de software, etc. El subgrupo de Carrera se enfoca en cosas como: promoción al ascenso laboral, educación para evaluaciones de desempeño laboral, etc. Finalmente, el subgrupo de Comunidad organiza iniciativas y eventos que contribuyen a crear mayores conexiones interpersonales. Todo ingeniero de frontend en Lyft puede formar parte del Grupo de Trabajo de Frontend.

Todos los miembros de frontend estamos vinculados mediante el Grupo de Trabajo de Frontend.

Además de lo anterior, contamos con un equipo dedicado de Infraestructura de Frontend (Frontend Infrastructure); éste existe dentro de la vertical de Infraestructura y su única misión es dar apoyo y mejorar la experiencia de desarrollo frontend. Los miembros de este equipo se han encargado de la creación y el mantenimiento de Frontend Build, @lyft/service y todas las otras piezas de software que les rodean, así como documentación, sistemas de ayuda y asistencia al desarrollador. Tener un equipo dedicado para esta importante labor ha sido clave para iterar rápidamente en la mejora de las herramientas y de los procesos de desarrollo de software a través de toda la organización de Frontend.

Frontend lo hacemos todos

El trabajo de frontend en Lyft es importante, diverso y emocionante. Aunque nuestra organización se ha robustecido al paso de los años, aún somos muy flexibles y cualquiera tiene la oportunidad de crear un gran impacto con su labor. Algunos ejemplos:

  • Un par de ingenieros de frontend recientemente propusieron la adopción de xstate para manejar máquinas de estados; esta tecnología se ha vuelto una parte opcional de nuestro stack de manejo de estados.
  • Un grupo de ingenieros se está encargando de atacar las oportunidades de mejora más fáciles en cuanto a desempeño web en nuestro stack.
  • Otro grupo está liderando una iniciativa interna para reconstruir nuestras pruebas de extremo a extremo usando la plataforma Cypress.
  • Otro conjunto de ingenieros está organizando la adopción de GraphQL a través de la organización mediante la construcción de herramientas y soporte interno.

Algunas muestras públicamente disponibles de nuestro trabajo las puedes encontrar en:

  • el sitio web de Lyft, con información sobre todo lo que concierne a Lyft;
  • nuestra página ride, en la que (si estás en Estados Unidos o Canadá) puedes pedir un viaje en este momento, sin necesidad de una app;
  • nuestros proyectos de código abierto con componentes frontend, tal como Clutch, nuestro plataforma extensible de administración de infraestructura; también proyectos que solían ser de Lyft y han sido donados a la comunidad de código abierto, como Amundsen, un motor de descubrimiento de datos y metadatos, o Flyte, una plataforma de machine learning y procesamiento de datos.

Siempre estamos buscando más colaboradores ansiosos por construir Lyft junto con nosotros. Si quieres ser parte de esta historia, ¡por favor considera unirte a nuestro equipo!

Gracias a Andrew Hao, Jamie Cohen, Alex Ung, Sheng Hong Tan y Temo Ojeda por su colaboración en este artículo.

Este artículo también está disponible en inglés: eng.lyft.com

--

--