Desatando los Proxies de Objetos: Construyendo Envoltorios Tipo-Seguros para Cualquier Cosa

Rate this content
Bookmark

Tal vez hayas o no hayas oído hablar de los proxies de objetos antes, pero ¿alguna vez has entendido cómo usarlos? ¿Cuál es el caso de uso real de un proxy de objeto? En esta charla, haremos una inmersión profunda en los proxies de objetos, comprendiendo cómo funcionan y los tipos de cosas que puedes construir utilizando ellos. Construiremos envoltorios de alto nivel para bibliotecas existentes y aprenderemos cómo envolverlos de manera tipo-segura.

Akash Joshi
Akash Joshi
16 min
21 Sep, 2023

Comments

Sign in or register to post your comment.

Video Summary and Transcription

Los proxies de objetos son middleware para objetos que permiten controlar la entrada y salida. Tienen varios casos de uso, como controlar el acceso a datos, agregar registros y manejar respuestas. Implementar proxies de objetos implica transpilar llamadas en solicitudes de red y manejar el acceso a propiedades y llamadas a métodos. Manejar trampas y errores de proxies de objetos implica falsificar la estructura del objeto, registrar objetos y propiedades objetivo y resolver errores. Realizar llamadas a API con proxies de objetos implica definir el tipo correcto, realizar llamadas al backend y envolver los métodos para devolver promesas. Los proxies de objetos se utilizan ampliamente en bibliotecas ORM y RPC y se deben explorar y experimentar.

Available in English

1. Introducción a los Proxies de Objetos

Short description:

Voy a hablar sobre cómo desatar los proxies de objetos, construyendo envoltorios seguros por tipo para cualquier cosa. Los proxies de objetos son middleware para tus objetos que te permiten controlar la entrada y salida. Tienen varios casos de uso como controlar el acceso a los datos, agregar registros y manejar respuestas. Prisma y PRPC son ejemplos de frameworks que utilizan proxies de objetos para acceder a bases de datos y habilitar llamadas de métodos transparentes.

Hola chicos, mi nombre es Akash Joshi. Soy un ingeniero de software en SIGTECH y hoy voy a hablar sobre cómo desatar los proxies de objetos, construyendo envoltorios seguros por tipo para cualquier cosa. Los proxies de objetos son una herramienta increíblemente útil pero poco explorada que se utiliza ampliamente en todas las bibliotecas que usamos en nuestro día a día. Así que voy a explicar cómo funcionan, qué son y cómo puedes usarlos también.

Entonces, ¿qué son los proxies de objetos? Los proxies de objetos son básicamente middleware para tus objetos. Así que piensa en ellos como un envoltorio alrededor de tu objeto con el que puedes controlar qué entrada llega al objeto y qué devuelves del objeto cuando un usuario intenta acceder a un método o una propiedad. Entonces, ¿cuáles son algunos de los casos de uso que vemos con los proxies de objetos en la vida real? Uno de los primeros casos de uso que se nos ocurre es controlar el acceso a los datos. Por ejemplo, realizar validación de entrada o implementar una capa de control de acceso en cualquier tipo de objeto que pueda contener propiedades privilegiadas. Por ejemplo, en un banco, si quieres crear un objeto que contenga los datos del usuario, en función de si un usuario o uno de tus desarrolladores tiene acceso a esa propiedad o no, puedes realizar validación de entrada en ella. Entonces, si el usuario o el desarrollador tiene acceso a esa propiedad, entonces la devuelves, de lo contrario puedes devolver un error o lo que quieras hacer en su lugar.

De manera similar, puedes agregar registros a tus objetos a través de los proxies de objetos. Por ejemplo, si un usuario intenta acceder repetidamente a datos no autorizados, o si simplemente quieres tener un registro de todas las actividades que tus desarrolladores están realizando en cualquier objeto privilegiado, entonces puedes agregar registros a través de los proxies de objetos. Todos los accesos se registran en uno de tus registros de acceso. Pero lo más importante, para lo que usamos los proxies de objetos es el manejo de respuestas. Esto puede implicar devolver algo diferente en función de lo que el usuario proporcione o cargar en memoria de forma diferida ciertos objetos. Por ejemplo, siguiendo con el caso de uso del usuario. Digamos que tenemos un objeto que contiene los detalles bancarios de un usuario, como su historial de direcciones y su historial de transacciones, entre otras cosas. Pero no quieres obtener todo esto en tiempo de ejecución. Entonces, cada vez que alguien intenta acceder a su historial de direcciones, hacemos una llamada a la API de direcciones para obtener todos esos datos y luego los devolvemos como resultado. Así que desde el lado del desarrollador, parece que hiciste una llamada a una propiedad, como user.address. Pero en el backend, en realidad se realiza una llamada a la API. Y también puedes implementar almacenamiento en caché y otras cosas encima de esto para hacer que tus llamadas a objetos sean más rápidas.

En la práctica, los proxies de objetos son utilizados por Prisma. ¿Alguna vez te has preguntado cómo Prisma sabe cuáles son todas tus tablas y cómo puede acceder a todas ellas en tiempo de ejecución, aunque en realidad no estén presentes en su código fuente? Lo que hacen es generar los tipos para todas tus tablas y luego los aplican a un proxy de objeto. Así que cada vez que accedes a una propiedad utilizando el método de punto, como prisma.analytics, prisma.user, prisma.posts, lo que realmente hace es realizar una llamada a la red a través de los proxies de objeto para acceder a la base de datos real y luego obtener esos resultados y devolverlos a tu cliente. Por supuesto, no está todo codificado en el código base de Prisma, sino que se genera en tiempo de ejecución a través de TypeScript y luego los proxies de objetos se encargan del resto. De manera similar, PRPC funciona con un concepto similar donde te permite realizar llamadas a objetos y llamadas a métodos desde tu frontend a tu backend de manera bastante transparente. También utilizan proxies de objetos. Exponen un objeto enrutador en el backend y exponen sus tipos y luego utilizan esos tipos en el frontend.

2. Implementando Proxies de Objetos

Short description:

La proxyización real ocurre en el frontend donde cualquier llamada a una de sus consultas es transpilada por el proxy de objeto en una llamada de red. Vamos a implementar una versión simple de la biblioteca TRPC y explicar cómo funcionan los proxies de objetos. En el servidor, tenemos un servidor Fastify con una ruta que acepta un nombre de procedimiento y parámetros, los aplica al procedimiento y devuelve la respuesta. El objeto API proporcionado por el desarrollador contiene las APIs expuestas. En el lado del cliente, definimos un proxy de objeto para acceder a propiedades y realizar llamadas a métodos. Utilizamos las propiedades get, has y apply del proxy para manejar el acceso a propiedades y las llamadas a métodos.

Entonces, la proxyización real ocurre en el frontend donde cualquier llamada a una de sus consultas es realmente transpilada por el proxy de objeto en una llamada de red y luego la llamada de red se ejecuta en el backend para devolverte el resultado en el frontend. Así que lo que vamos a hacer ahora es implementar una versión muy simple de la biblioteca TRPC o intentar implementar un poco de RPC al backend nosotros mismos utilizando proxies de objetos. También voy a explicar cómo funcionan los proxies de objetos. Esto solo implica un poco de código. En primer lugar, veamos cómo se ve nuestro servidor. Este es un servidor Fastify muy simple. Si vas a la página de documentación de Fastify, esto es similar a lo que verás en la página principal. De hecho, esto es lo que he copiado de allí. La única ruta que he agregado aquí es /RPC. Acepta un nombre de procedimiento y un conjunto de parámetros para ese procedimiento. Luego, analiza esto a esta cadena de datos y luego aplica esos parámetros a ese procedimiento y luego devuelve la respuesta al frontend.

¿De dónde obtenemos el procedimiento real? Digamos que tenemos un objeto API que el desarrollador proporciona al servidor y este objeto API contiene todas las APIs que el desarrollador realmente quiere exponer al cliente. En este caso, estamos exponiendo hello, que simplemente devuelve world, y luego otro método llamado sum, que devuelve la suma de dos números. Y observa cómo hemos definido correctamente los tipos aquí. Esto se debe a que vamos a usar las propiedades de TypeScript para pasar ese tipo también al cliente.

En el lado del cliente, lo que vamos a hacer ahora es definir un proxy de objeto muy simple. Echa un vistazo al método principal aquí donde voy a definir algunas líneas de código que intentan acceder a algunas propiedades del proxy de objeto y tratan de obtener los resultados de ello. El primero es que intentamos destruir una propiedad llamada hello en un objeto que aún no existe. Luego verificamos dos propiedades para ver si existen en el objeto y por último intentamos hacer llamadas a métodos en el proxy de objeto y luego mostramos el resultado de ello en la consola. Así que definamos rápidamente nuestro proxy de objeto aquí. La sintaxis para definir proxies de objetos es usar un nuevo proxy para definirlos. El primer parámetro que toma es el objeto objetivo en el que quieres construirlo. La forma estándar sería usar un envoltorio sobre un objeto existente. En este caso, vamos a usar solo las propiedades del envoltorio, por lo que paso un objeto vacío.

A continuación, vamos a ver todas las propiedades que acepta un proxy. Principalmente son get, has y apply. Estas son las propiedades en las que te centrarás principalmente al construir proxies de objetos. La propiedad get es el método de punto, por lo que cuando estás destruyendo hello o estás haciendo proxy de cliente.punto o proxy de cliente.cualquierotracosa, entonces se llama al método get y puedes devolver lo que quieras desde él. El método has es como hasOwnProperty, que verifica si una propiedad existe en el proxy de objeto o no, y en este caso simplemente devolvemos true, por lo que estos dos métodos que verifican si estos dos parámetros existen en la propiedad del objeto deben devolver true aunque en realidad no existan allí, y por último tenemos apply. No creo que tengamos suficiente tiempo para profundizar en ello, pero es una trampa para cualquier llamada a métodos que hagas en tu proxy de objeto. En este caso, get debería ser suficiente, profundizaremos en ello a medida que lo definamos.

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

A Guide to React Rendering Behavior
React Advanced Conference 2022React Advanced Conference 2022
25 min
A Guide to React Rendering Behavior
Top Content
React is a library for "rendering" UI from components, but many users find themselves confused about how React rendering actually works. What do terms like "rendering", "reconciliation", "Fibers", and "committing" actually mean? When do renders happen? How does Context affect rendering, and how do libraries like Redux cause updates? In this talk, we'll clear up the confusion and provide a solid foundation for understanding when, why, and how React renders. We'll look at: - What "rendering" actually is - How React queues renders and the standard rendering behavior - How keys and component types are used in rendering - Techniques for optimizing render performance - How context usage affects rendering behavior| - How external libraries tie into React rendering
Scaling Up with Remix and Micro Frontends
Remix Conf Europe 2022Remix Conf Europe 2022
23 min
Scaling Up with Remix and Micro Frontends
Top Content
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.
React Concurrency, Explained
React Summit 2023React Summit 2023
23 min
React Concurrency, Explained
Top Content
React 18! Concurrent features! You might’ve already tried the new APIs like useTransition, or you might’ve just heard of them. But do you know how React 18 achieves the performance wins it brings with itself? In this talk, let’s peek under the hood of React 18’s performance features: - How React 18 lowers the time your page stays frozen (aka TBT) - What exactly happens in the main thread when you run useTransition() - What’s the catch with the improvements (there’s no free cake!), and why Vue.js and Preact straight refused to ship anything similar
Full Stack Components
Remix Conf Europe 2022Remix Conf Europe 2022
37 min
Full Stack Components
Top Content
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.
Making JavaScript on WebAssembly Fast
JSNation Live 2021JSNation Live 2021
29 min
Making JavaScript on WebAssembly Fast
Top Content
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.
Debugging JS
React Summit 2023React Summit 2023
24 min
Debugging JS
Top Content
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 Hooks Tips Only the Pros Know
React Summit Remote Edition 2021React Summit Remote Edition 2021
177 min
React Hooks Tips Only the Pros Know
Top Content
Featured Workshop
Maurice de Beijer
Maurice de Beijer
The addition of the hooks API to React was quite a major change. Before hooks most components had to be class based. Now, with hooks, these are often much simpler functional components. Hooks can be really simple to use. Almost deceptively simple. Because there are still plenty of ways you can mess up with hooks. And it often turns out there are many ways where you can improve your components a better understanding of how each React hook can be used.You will learn all about the pros and cons of the various hooks. You will learn when to use useState() versus useReducer(). We will look at using useContext() efficiently. You will see when to use useLayoutEffect() and when useEffect() is better.
Designing Effective Tests With React Testing Library
React Summit 2023React Summit 2023
151 min
Designing Effective Tests With React Testing Library
Top Content
Featured Workshop
Josh Justice
Josh Justice
React Testing Library is a great framework for React component tests because there are a lot of questions it answers for you, so you don’t need to worry about those questions. But that doesn’t mean testing is easy. There are still a lot of questions you have to figure out for yourself: How many component tests should you write vs end-to-end tests or lower-level unit tests? How can you test a certain line of code that is tricky to test? And what in the world are you supposed to do about that persistent act() warning?
In this three-hour workshop we’ll introduce React Testing Library along with a mental model for how to think about designing your component tests. This mental model will help you see how to test each bit of logic, whether or not to mock dependencies, and will help improve the design of your components. You’ll walk away with the tools, techniques, and principles you need to implement low-cost, high-value component tests.
Table of contents- The different kinds of React application tests, and where component tests fit in- A mental model for thinking about the inputs and outputs of the components you test- Options for selecting DOM elements to verify and interact with them- The value of mocks and why they shouldn’t be avoided- The challenges with asynchrony in RTL tests and how to handle them
Prerequisites- Familiarity with building applications with React- Basic experience writing automated tests with Jest or another unit testing framework- You do not need any experience with React Testing Library- Machine setup: Node LTS, Yarn
Using CodeMirror to Build a JavaScript Editor with Linting and AutoComplete
React Day Berlin 2022React Day Berlin 2022
86 min
Using CodeMirror to Build a JavaScript Editor with Linting and AutoComplete
Top Content
WorkshopFree
Hussien Khayoon
Kahvi Patel
2 authors
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.
Testing Web Applications Using Cypress
TestJS Summit - January, 2021TestJS Summit - January, 2021
173 min
Testing Web Applications Using Cypress
WorkshopFree
Gleb Bahmutov
Gleb Bahmutov
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.
Build a powerful DataGrid in few hours with Ag Grid
React Summit US 2023React Summit US 2023
96 min
Build a powerful DataGrid in few hours with Ag Grid
WorkshopFree
Mike Ryan
Mike Ryan
Does your React app need to efficiently display lots (and lots) of data in a grid? Do your users want to be able to search, sort, filter, and edit data? AG Grid is the best JavaScript grid in the world and is packed with features, highly performant, and extensible. In this workshop, you’ll learn how to get started with AG Grid, how we can enable sorting and filtering of data in the grid, cell rendering, and more. You will walk away from this free 3-hour workshop equipped with the knowledge for implementing AG Grid into your React application.
We all know that rolling our own grid solution is not easy, and let's be honest, is not something that we should be working on. We are focused on building a product and driving forward innovation. In this workshop, you'll see just how easy it is to get started with AG Grid.
Prerequisites: Basic React and JavaScript
Workshop level: Beginner
0 to Auth in an Hour Using NodeJS SDK
Node Congress 2023Node Congress 2023
63 min
0 to Auth in an Hour Using NodeJS SDK
WorkshopFree
Asaf Shen
Asaf Shen
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