Generación de Código Tipado

Rate this content
Bookmark

Durante los últimos seis años en Rollbar, el equipo de ingeniería ha estado trabajando incansablemente para migrar nuestra aplicación heredada a una pila tecnológica moderna de Javascript. Hemos aprovechado Next.js, GraphQL y varias otras herramientas de JS para lanzar más características, hacer que nuestro equipo de desarrollo esté más feliz y lograr una impresionante reducción de 7 veces en el rendimiento de nuestra aplicación p99. Te invito a que me acompañes mientras presento las diversas técnicas y arquitectura que elegimos utilizar para migrar rápidamente desde nuestro monolito heredado.

22 min
21 Sep, 2023

Comments

Sign in or register to post your comment.

AI Generated Video Summary

Hoy voy a hablar sobre cómo la generación de tipos ayudó a reducir errores y mejorar nuestra experiencia como desarrolladores en Rollbar. La pila tecnológica de Monolith se construye principalmente en Python Pyramid, un marco web similar a Django, Ruby on Rails o Express. Para abordar los desafíos de depuración, rendimiento y navegación de código, nos hemos migrado a una pila tecnológica que incluye TypeScript, Next.js, GraphQL y React Query. Codegen se utiliza para generar código TypeScript tanto en el lado del servidor como en el lado del cliente, mejorando la depuración, el rendimiento y la navegación de código.

1. Introducción a Rollbar Monolith y Tech Stack

Short description:

Hoy voy a hablar sobre cómo la generación de tipos ayudó a reducir errores y mejorar nuestra experiencia como desarrolladores en Rollbar. Daré una visión general de la arquitectura que decidimos implementar. La pila tecnológica Monolith está construida principalmente en Python Pyramid, un marco web similar a Django, Ruby on Rails o Express.

Hola a todos. Hoy voy a hablar sobre cómo la generación de tipos ayudó a reducir errores y mejorar nuestra experiencia como desarrolladores en Rollbar. Soy Paul Sereno. Soy un ingeniero de software senior en Rollbar. Tengo unos 10 años de experiencia como desarrollador de software, trabajando en aplicaciones basadas en web, y vivo en Austin, Texas. Para la agenda de hoy, primero daré una breve introducción al monolito de Rollbar. Hablaré sobre algunos de los desafíos técnicos que experimentamos al mantener el código del monolito. Y explicaré por qué tomamos la decisión de migrar nuestra base de código a TypeScript. Luego hablaré sobre la estrategia de migración a TypeScript, y daré una visión general de la arquitectura que decidimos implementar. Después de eso, hablaré sobre cómo estábamos usando GraphQL Code Gen en Rollbar, y proporcionaré algunos ejemplos de código que demostrarán las diferentes formas en que estamos utilizando Code Gen tanto en el lado del servidor como en el lado del cliente de nuestra aplicación.

De acuerdo, primero vamos a revisar la aplicación Monolith. La pila tecnológica Monolith está construida principalmente en Python Pyramid, un marco web similar a Django, Ruby on Rails o Express. Estamos utilizando varias tecnologías de base de datos como MySQL, Elasticsearch y Clickhouse. El front-end está escrito en React 16, por lo que no hay hooks y todo está estilizado usando una combinación de Sass y CSS.

2. Migración a Nueva Pila Tecnológica

Short description:

A lo largo de los años, el Monolith ha tenido 78 colaboradores, más de 44,000 commits y más de 9,000 pull requests. Desarrollar y desplegar en una base de código monolítica tiene sus beneficios, como procesos de desarrollo y despliegue más sencillos. Sin embargo, la depuración, el rendimiento y la navegación del código han sido desafíos significativos. Para abordar estos problemas, decidimos migrar a una nueva pila tecnológica que incluye TypeScript, Next.js, GraphQL y React Query. Esta pila tecnológica nos permite aprovechar la seguridad de tipos, la flexibilidad en las migraciones del backend y las llamadas eficientes a la API a través de React Query.

A lo largo de los años, el Monolith ha tenido 78 colaboradores, más de 44,000 commits y más de 9,000 pull requests, y tiene 11 años de antigüedad. Hay algunos beneficios de trabajar en una base de código monolítica. Es mucho más fácil desarrollar en una base de código monolítica, porque a menudo hay código de plantilla que los desarrolladores pueden copiar y pegar y ajustar para hacer que algo funcione más rápido. Desarrollar una aplicación monolítica a veces es más fácil si puedes encajar todo en una... Disculpen por eso.

Desplegar una aplicación monolítica a veces es más fácil porque puedes encajar todo en un solo Dockerfile. Y la búsqueda de código a menudo es una mejor experiencia en aplicaciones monolíticas porque una línea de código que deseas buscar está en un solo repositorio. Por lo tanto, es mucho más fácil buscar líneas de código individuales.

Algunos de los desafíos que experimentamos al trabajar en nuestras aplicaciones monolíticas han sido la depuración, que ha sido un gran desafío porque hay mucho código que debes leer para comprender completamente la causa raíz de ciertos problemas. Nosotros mismos usamos Rollbar para clasificar los problemas, y aunque las funciones de agrupación que proporciona Rollbar son buenas, todavía nos resulta difícil identificar la causa raíz de algunas partes del código que son realmente complejas. El rendimiento es otro problema con nuestra base de código monolítica, y se debe principalmente a un código ineficiente. Por ejemplo, cosas como hacer llamadas duplicadas a la base de datos y realizar un procesamiento pesado después de obtener los datos han sido un cuello de botella bastante grande. También hemos experimentado problemas al navegar por el código. A veces puede llevar horas comprender completamente cómo funcionan algunas cosas. Dado estos problemas, decidimos tomar la decisión de migrar lejos de trabajar en una aplicación monolítica hacia una nueva pila tecnológica.

Y esa pila tecnológica incluye TypeScript. Por lo tanto, la nueva pila tecnológica aprovecha Next.js, GraphQL y React Query para ayudar a resolver algunos de los problemas relacionados con nuestra aplicación monolítica. Y, por supuesto, todo está escrito en TypeScript. La nueva pila tecnológica a la que estamos migrando todavía utiliza partes de la aplicación monolítica. Hemos hecho que esas características del monolito estén disponibles a través de varios puntos finales de API internos. El servidor GraphQL se utiliza esencialmente como un proxy de API que se encuentra entre nuestra API interna y nuestra aplicación front-end. Decidimos utilizar GraphQL de esta manera porque no solo proporciona seguridad de tipos entre el servidor y el cliente, sino que también nos brinda flexibilidad en términos de migraciones del backend. Por ejemplo, planeamos reemplazar algunos de los puntos finales de API internos con llamadas gRPC. En esta arquitectura de proxy, podemos experimentar con diferentes soluciones de backend. Todas nuestras llamadas a la API desde el front-end se realizan a través de React Query. Y el cliente de React Query que estamos utilizando se genera completamente a partir de las consultas de GraphQL en sí. Hablaré de eso en un momento. Esta configuración nos ha permitido obtener mucha seguridad de tipos en el front-end. Mencioné que generamos nuestro cliente front-end. Específicamente, utilizamos una herramienta llamada GraphQL Codegen.

3. Usando Codegen para Generación de Tipos

Short description:

Usamos Codegen para generar código TypeScript tanto en el servidor como en el cliente. Proporciona una herramienta de línea de comandos fácil de usar. Para las funciones de resolución, agregamos manualmente tipos para garantizar la seguridad de tipos. Codegen permite la configuración de anulaciones para la generación de tipos. En el lado del cliente, Codegen puede generar hooks seguros en cuanto a tipos a partir de consultas GraphQL. La migración a esta arquitectura mejora la depuración, el rendimiento y la navegación del código. TypeScript mejora la experiencia del desarrollador al permitir el trabajo en paralelo.

Y esta es una herramienta de código abierto que generará automáticamente código TypeScript a partir de un esquema GraphQL o una operación de consulta GraphQL. Por lo tanto, usamos Codegen tanto en el servidor como en el cliente. En el lado del servidor, lo usamos para generar tipos para nuestros resolutores GraphQL. Y en el cliente, lo usamos para generar el cliente de

Daré algunos ejemplos de las diferencias entre cómo lo usamos en el servidor y en el cliente. Usar Codegen en sí es bastante fácil. Codegen proporciona una herramienta de línea de comandos que es bastante fácil de usar. Solo tienes que ejecutar Codegen y darle una configuración.

Quiero dar un ejemplo específico de cómo estamos usando Codegen en el servidor. Este es un fragmento de código tomado de nuestra base de código. Esto representa el esquema de conexión de entorno que está diseñado para representar una lista de entornos de proyecto. Y usar la nomenclatura de conexión de código es común en GraphQL cuando se representa listas paginadas de data. El resolutor para esta conexión simplemente obtiene de la base de datos los entornos del proyecto y devuelve una lista de entornos.

Uno de los problemas que encontramos al usar TypeScript en GraphQL ha sido agregar seguridad de tipos a estas funciones de resolución. Por ejemplo, de forma predeterminada, los argumentos como límite, después de filtro no generan tipos para ellos. Por lo tanto, tenemos que agregar manualmente los tipos nosotros mismos. Este es un ejemplo de un tipo que definimos explícitamente para esos argumentos del resolutor. Y Codegen de GraphQL proporciona una solución alternativa para estos problemas. Te permite agregar explícitamente una configuración para anular su generación interna. Por ejemplo, en este caso, estamos anulando la generación de la conexión de entorno usando nuestros tipos definidos explícitamente aquí. En el modelo de conexiones de entorno, se asigna a la definición del esquema de conexión de entorno.

En el lado del cliente, puedes usar la herramienta de línea de comandos de la misma manera simplemente llamando a CodeGen de GraphQL. La generación de código es mucho más fácil en el cliente. Dada una consulta GraphQL como esta, en este ejemplo estamos obteniendo una lista de entornos de nuestro servidor GraphQL. Y podemos generar un hook a partir de esa consulta usando CodeGen de GraphQL. Este hook obtendrá los datos que necesitamos y será completamente seguro en cuanto a tipos. Entonces, en este ejemplo, como puedes ver, cuando llamas o escribes en tu editor de texto query.results, podrás ver los diferentes atributos que tiene ese objeto.

Algunos de los beneficios que hemos experimentado al migrar a esta arquitectura han sido la depuración. Es mucho más fácil que el comprobador de tipos detecte posibles problemas. El rendimiento, hay varias optimizaciones en tiempo de compilación que se pueden obtener al tener tu base de código en TypeScript, y hemos visto un aumento en el rendimiento de nuestra aplicación. En cuanto a la navegación en la base de código, tener esas anotaciones de tipo ha hecho que trabajar con bibliotecas internas sea mucho más fácil de usar, especialmente bibliotecas que no tienen una muy buena documentación. Y un beneficio adicional de usar TypeScript ha sido mejorar nuestra experiencia general como desarrolladores, ya que ha permitido a los desarrolladores de front-end y back-end trabajar en paralelo sin depender uno del otro.

Algunas de mis reflexiones finales son que migrar una base de código monolítica es un desafío, pero con la arquitectura adecuada, incluso un equipo pequeño puede hacerlo posible. Hemos obtenido muchos beneficios al configurar esos puntos finales internos y simplemente usar GraphQL como un proxy para nuestra API interna. Y en general, TypeScript mejoró nuestra capacidad para depurar y optimizar nuestro código. Eso es todo. Gracias.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Remix Conf Europe 2022Remix Conf Europe 2022
23 min
Scaling Up with Remix and Micro Frontends
Do you have a large product built by many teams? Are you struggling to release often? Did your frontend turn into a massive unmaintainable monolith? If, like me, you’ve answered yes to any of those questions, this talk is for you! I’ll show you exactly how you can build a micro frontend architecture with Remix to solve those challenges.
Remix Conf Europe 2022Remix Conf Europe 2022
37 min
Full Stack Components
Remix is a web framework that gives you the simple mental model of a Multi-Page App (MPA) but the power and capabilities of a Single-Page App (SPA). One of the big challenges of SPAs is network management resulting in a great deal of indirection and buggy code. This is especially noticeable in application state which Remix completely eliminates, but it's also an issue in individual components that communicate with a single-purpose backend endpoint (like a combobox search for example).
In this talk, Kent will demonstrate how Remix enables you to build complex UI components that are connected to a backend in the simplest and most powerful way you've ever seen. Leaving you time to chill with your family or whatever else you do for fun.
JSNation Live 2021JSNation Live 2021
29 min
Making JavaScript on WebAssembly Fast
JavaScript in the browser runs many times faster than it did two decades ago. And that happened because the browser vendors spent that time working on intensive performance optimizations in their JavaScript engines.Because of this optimization work, JavaScript is now running in many places besides the browser. But there are still some environments where the JS engines can’t apply those optimizations in the right way to make things fast.We’re working to solve this, beginning a whole new wave of JavaScript optimization work. We’re improving JavaScript performance for entirely different environments, where different rules apply. And this is possible because of WebAssembly. In this talk, I'll explain how this all works and what's coming next.
React Summit 2023React Summit 2023
24 min
Debugging JS
As developers, we spend much of our time debugging apps - often code we didn't even write. Sadly, few developers have ever been taught how to approach debugging - it's something most of us learn through painful experience.  The good news is you _can_ learn how to debug effectively, and there's several key techniques and tools you can use for debugging JS and React apps.

Workshops on related topic

React Advanced Conference 2021React Advanced Conference 2021
174 min
React, TypeScript, and TDD
Featured WorkshopFree
ReactJS is wildly popular and thus wildly supported. TypeScript is increasingly popular, and thus increasingly supported.

The two together? Not as much. Given that they both change quickly, it's hard to find accurate learning materials.

React+TypeScript, with JetBrains IDEs? That three-part combination is the topic of this series. We'll show a little about a lot. Meaning, the key steps to getting productive, in the IDE, for React projects using TypeScript. Along the way we'll show test-driven development and emphasize tips-and-tricks in the IDE.
React Advanced Conference 2022React Advanced Conference 2022
148 min
Best Practices and Advanced TypeScript Tips for React Developers
Featured Workshop
Are you a React developer trying to get the most benefits from TypeScript? Then this is the workshop for you.In this interactive workshop, we will start at the basics and examine the pros and cons of different ways you can declare React components using TypeScript. After that we will move to more advanced concepts where we will go beyond the strict setting of TypeScript. You will learn when to use types like any, unknown and never. We will explore the use of type predicates, guards and exhaustive checking. You will learn about the built-in mapped types as well as how to create your own new type map utilities. And we will start programming in the TypeScript type system using conditional types and type inferring.
React Day Berlin 2022React Day Berlin 2022
86 min
Using CodeMirror to Build a JavaScript Editor with Linting and AutoComplete
WorkshopFree
Using a library might seem easy at first glance, but how do you choose the right library? How do you upgrade an existing one? And how do you wade through the documentation to find what you want?
In this workshop, we’ll discuss all these finer points while going through a general example of building a code editor using CodeMirror in React. All while sharing some of the nuances our team learned about using this library and some problems we encountered.
TestJS Summit - January, 2021TestJS Summit - January, 2021
173 min
Testing Web Applications Using Cypress
WorkshopFree
This workshop will teach you the basics of writing useful end-to-end tests using Cypress Test Runner.
We will cover writing tests, covering every application feature, structuring tests, intercepting network requests, and setting up the backend data.
Anyone who knows JavaScript programming language and has NPM installed would be able to follow along.
Node Congress 2023Node Congress 2023
63 min
0 to Auth in an Hour Using NodeJS SDK
WorkshopFree
Passwordless authentication may seem complex, but it is simple to add it to any app using the right tool.
We will enhance a full-stack JS application (Node.JS backend + React frontend) to authenticate users with OAuth (social login) and One Time Passwords (email), including:- User authentication - Managing user interactions, returning session / refresh JWTs- Session management and validation - Storing the session for subsequent client requests, validating / refreshing sessions
At the end of the workshop, we will also touch on another approach to code authentication using frontend Descope Flows (drag-and-drop workflows), while keeping only session validation in the backend. With this, we will also show how easy it is to enable biometrics and other passwordless authentication methods.
Table of contents- A quick intro to core authentication concepts- Coding- Why passwordless matters
Prerequisites- IDE for your choice- Node 18 or higher
TypeScript Congress 2022TypeScript Congress 2022
116 min
Advanced TypeScript types for fun and reliability
Workshop
If you're looking to get the most out of TypeScript, this workshop is for you! In this interactive workshop, we will explore the use of advanced types to improve the safety and predictability of your TypeScript code. You will learn when to use types like unknown or never. We will explore the use of type predicates, guards and exhaustive checking to make your TypeScript code more reliable both at compile and run-time. You will learn about the built-in mapped types as well as how to create your own new type map utilities. And we will start programming in the TypeScript type system using conditional types and type inferring.
Are you familiar with the basics of TypeScript and want to dive deeper? Then please join me with your laptop in this advanced and interactive workshop to learn all these topics and more.
You can find the slides, with links, here: http://theproblemsolver.nl/docs/ts-advanced-workshop.pdf
And the repository we will be using is here: https://github.com/mauricedb/ts-advanced