Construyendo un Servidor Web Hiper Rápido con Deno

Rate this content
Bookmark

Deno 1.9 introdujo una nueva API de servidor web que aprovecha Hyper, una implementación rápida y correcta de HTTP para Rust. El uso de esta API en lugar de la implementación std/http aumenta el rendimiento y proporciona soporte para HTTP2. En este masterclass, aprende cómo crear un servidor web utilizando Hyper en el fondo y mejorar el rendimiento de tus aplicaciones web.

Matt Landers
Matt Landers
Will Johnston
Will Johnston
156 min
16 Jun, 2021

Comments

Sign in or register to post your comment.

Video Summary and Transcription

El masterclass presenta Beano y Hyper, un tiempo de ejecución de JavaScript y una biblioteca de Rust conocida por su implementación rápida de HTTP. Se discuten los beneficios de usar Rust e Hyper en lugar de la implementación estándar de TypeScript de HTTP. Las pruebas de carga muestran que Hyper es aproximadamente un 35% más rápido. Se explica el proceso de construcción de un marco web llamado Hyperbole, junto con la implementación de la lógica de manejo de solicitudes y middleware. Se explora el uso de Deno para bibliotecas y producción, y se enfatiza la importancia de las pruebas de carga y la optimización.

Available in English

1. Introducción a Beano y Hyper

Short description:

Hola. Soy Matt Landers. Vamos a construir un servidor web ultrarrápido con Beano. Beano es un tiempo de ejecución de JavaScript que admite TypeScript de forma nativa. Hyper es una biblioteca de Rust conocida por su implementación correcta y rápida de HTTP. Emocionado por la integración de Beano 1.9.

♪ Hola. Soy Matt Landers. Soy el jefe de DevRel en WP Engine, y estoy acompañado por... con Will Johnston. Ambos estamos haciendo esta sesión juntos. Vamos a construir algo con Beano. Así que vamos a construir un servidor web ultrarrápido con Beano.

¿Qué estabas diciendo, Will? Dije, hola, chicos. Hola. Will, buenos días. Es temprano para mí. Es temprano para mí. Tal vez no tan temprano para Matt. Y no sé cómo será para el resto de todos. Es temprano para mí solo porque estoy de vacaciones, y... conduje 14 horas durante la noche. He dormido un poco desde entonces, pero tal vez un poco delirante, así que tal vez no todo salga tan bien como debería, pero estoy emocionado de hacer esto todavía.

Encontré un lugar con buena conexión a internet y debería estar... debería estar listo. Estoy realmente emocionado por Beano. Espero que todos aquí hayan oído hablar de Beano, pero solo daré una breve introducción. Beano es un tiempo de ejecución de JavaScript que admite TypeScript de forma nativa, lo cual es realmente increíble para mí porque me encanta TypeScript. Así que puedes crear un archivo TS, ejecutarlo con Beano y listo. No necesitas una configuración de TS ni nada por el estilo. Simplemente funciona. Beano está construido en Rust, lo cual es algo que vamos a aprovechar hoy. Así que cuando decimos construir un servidor web ultrarrápido con Beano, Hyper es una biblioteca de Rust que es una implementación de HTTP. Y se sabe que es muy correcta en su implementación y muy rápida.

Sí, segura en memoria. Ya he usado Rust e Hyper antes. Así que cuando esta integración llegó en Beano 1.9, estaba súper emocionado al respecto.

2. Beneficios de Rust y Hyper

Short description:

Will discute los beneficios de usar Rust y las mejoras de rendimiento de Hyper en comparación con la implementación estándar de TypeScript de HTTP. Planeamos construir una aplicación Hello World y un enrutador y servidor basados en Express. También mencionamos el uso de OAK, un marco web, y ofrecemos soporte para preguntas y proporcionamos instrucciones de configuración.

¿Qué estabas diciendo, Will? Es seguro en memoria. Es seguro en memoria y Rust tiende a ser correcto, como te obliga a hacer las cosas correctamente. Eso no significa que no puedas cometer errores, obviamente, como tu lógica puede estar equivocada, pero te obliga a manejar las condiciones de error, si tienes una enumeración, debes hacer coincidir todas ellas y manejar cada caso. Así que hay muchas cosas en Rust que te obligan a hacer las cosas bien.

Bueno, y lo bueno de esto es que antes de Hyper, tenías una implementación estándar de TypeScript de HTTP, que funciona bien, pero es un poco más lento. Rust es un lenguaje de nivel inferior que JavaScript, por lo que Hyper tiene la capacidad de ser un poco mejor en el rendimiento. Correcto, y tenemos un rendimiento mucho mejor para algunas cosas. Sí, de hecho, estoy realmente impresionado con lo rápido que ha sido la biblioteca HTTP estándar, considerando que está completamente escrita en TypeScript. Así que vamos a escribir una pequeña aplicación Hello World con eso solo para ver cómo se ve eso, y lo usaremos para hacer algunas pruebas de carga para que podamos ver la diferencia cuando usemos Hyper.

Y luego, una vez que pasemos por una aplicación Hello World para Hyper, construiremos un enrutador y un servidor a su alrededor. Vamos a modelar esto según Express. Mi suposición es que la mayoría de las personas aquí han usado Node y probablemente tienen algo de experiencia con Express, así que vamos a hacer eso. Quiero decir, típicamente, si fuera a construir un nuevo marco desde cero con Deno, probablemente no modelaría Express. Haría algo más idiomático para Deno. Deno utiliza Web Standards en todos los aspectos, por lo que la mayoría de las cosas que están en Deno también están disponibles en el navegador, lo cual es genial. Así que usas Web Standards la mayor parte del tiempo. Hay cosas que he aprendido gracias a Deno que están en Web Standards y están disponibles en el navegador que no tenía idea de que estaban allí, lo cual ha sido genial. Cosas como objetos de solicitud y respuesta y cosas de nivel inferior que no pensé que estaban disponibles en el navegador, lo están, lo cual es genial.

Después de eso, crearemos un pequeño marco que haga enrutamiento y permita agregar middleware y luego, si tenemos tiempo al final, usaremos OAK. OAK es más un enfoque de servidor web idiomático escrito por alguien del equipo principal de Deno. Está disponible para usar, pero es un marco web. Así que cuando terminemos con esto, tendrás un pequeño marco web que has escrito tú mismo, lo cual será realmente genial para pasar por ese proceso y ver todas las cosas en las que tienes que pensar cuando estás construyendo un marco web. Pero no lo recomendaría para producción. OAK está bastante bien respaldado por la comunidad y te recomendaría que lo pruebes si vas a construir tu propio servidor, pero esto será genial para ver algunos de los aspectos internos de cómo funciona un marco web.

Y justo antes, o mientras Matt comienza aquí, si tienes alguna pregunta mientras avanzamos, puedes publicarlas en el chat o hay un canal de Discord para esta masterclass y haremos todo lo posible para responder mientras avanzamos. Bien, y trataré, si vamos demasiado rápido o algo así, solo avísanos o si necesitas una explicación o más información sobre lo que estamos haciendo, definitivamente avísanos. Así que estoy en una configuración extraña. Así que si me ves mover la mano, no sé si puedes verme siquiera, pero si me ves mover la mano. Tengo mi iPad aquí. Esa es mi segunda pantalla en este momento. Así que solo tengo algunas notas para seguir. Muy bien, aquí vamos. Así que ahora solo tengo una carpeta. No hay nada en ella. Así que necesitas tener Deno instalado. Necesitas tener al menos Deno 1.9 o superior. Hyper se agregó a la API de Deno en la versión 1.9. Todavía está en un estado inestable. Así que usaremos la bandera de inestable para esto. Tengo este otro archivo aquí. Oye, este es un probador de carga. Supongo que puedo abrirlo. Sí, lo voy a vincular en Discord y también lo vincularé aquí en el chat. Sí, esto es genial. Es un probador de carga. Es solo una utilidad de línea de comandos que puedes usar para generar carga en una URL. Y eso nos permitirá analizar el rendimiento de cada una de nuestras soluciones que creemos. Así que si quieres hacer eso con nosotros, definitivamente descarga HEI. Los ejecutables están aquí mismo. Solo los descargas y los ejecutas. Es posible que debas hacer chmod, luego mach1, chmod 777, luego el nombre del archivo. Muy bien, vamos a construir un pequeño servidor con Deno. Oh, otra cosa que necesitarás. Estoy en VS Code. Hay una extensión para Deno, si buscas Deno en tus extensiones. Es la que es de Denoland. Denoland es la organización en GitHub para Deno, y ellos mantienen esta extensión. Solía ser de terceros, y luego la trajeron, lo cual es genial. Así que obtén esa extensión. Eso te permitirá hacer cosas como esperas en el nivel superior, obtener los tipos para Deno, TypeScript y todo eso. Muy bien, lo primero que voy a hacer es configurar esto para Deno. Voy a hacer Comando-Mayús-P, y si escribes Deno, obtendrás inicializar la configuración de tu espacio de trabajo, y solo presiona Enter en eso, y creará un archivo de configuración de VS code para que VS code sepa que este es un proyecto de Deno, y la extensión ahora estará en uso. Muy bien, voy a crear una carpeta, y la llamaré STD, y vamos a crear la implementación de hello world aquí para la biblioteca estándar, y simplemente puedes crear un archivo TS, y mi iPad sigue quedando en blanco, así que no recuerdo el nombre exacto del módulo en el que lo vamos a poner. Muy bien. No necesitas clonar Hey. Hey, si quieres, acabo de vincularlo. Lo vamos a usar, pero es solo un probador de carga. No vamos a escribir ningún código ni nada por el estilo. Correcto, sí. Solo lo estamos usando para que cuando escribamos nuestro servidor, lo iniciemos, podemos apuntar Hey a eso y hacer que genere carga y ver cuántas solicitudes por segundo podemos obtener. Muy bien, lo primero que vamos a hacer es importar serve, y esta es la implementación de Hello World de la biblioteca estándar, solo para que te hagas una idea de cómo se ve. Deno utiliza módulos ESM, por lo que no tenemos que usar NPM install ni nada por el estilo. Literalmente podemos apuntar esto en Internet, y traerá estos archivos, lo cual es súper genial. Esa es una de las grandes innovaciones de Deno también es alejarse de NPM y la gestión de dependencias y permitirte hacerlo de una manera más amigable para la web. Sí, Brian, de hecho tenemos un enlace de GitHub para la masterclass que tiene la versión final de lo que estamos creando hoy, así que lo vincularé más tarde para que las personas puedan seguirlo y no estar buscando el código final mientras intentamos codificarlo. Estamos comenzando con una carpeta vacía, como puedes ver, Matt solo tiene su std / hello-world.ts y nada más, así que eso es con lo que empezamos hoy. Sí, esto es súper genial. Deno es genial. Si no lo has usado antes, sí, no tienes que hacer nada para la configuración. No necesito crear un NPM. No tengo que hacer ningún package.json ni nada por el estilo. Simplemente puedo crear un archivo TypeScript y comenzar a codificar y luego simplemente lo vamos a ejecutar. No hay más que hacer. Los paquetes pueden estar en caché localmente, por lo que lo que puedes hacer, si estás ejecutando el complemento de VS Code, puedes ir arriba y hacer clic derecho en él, creo, y potencialmente cachear el complemento. Y de esa manera estará disponible para ti. Sí, una cosa que me ha pasado ahora mismo es que no encuentra estas cosas. Así que a veces, después de inicializar la extensión, necesito reiniciar VS Code, así que voy a hacer eso rápidamente. Así que es posible que también necesites hacer eso. Si ves ondas rojas debajo de la importación, entonces tendrás que hacer eso. Así que ahora desaparecieron, así que estoy listo para continuar.

3. Creación de un Servidor y Ejecución de Pruebas de Carga

Short description:

Creamos un servidor y lo usamos para escuchar. Deno admite esperas en el nivel superior y tiene soporte incorporado para generadores e iterables. Ejecutamos el servidor en el puerto 3000 y respondemos con un estado 200 y el cuerpo 'hello world'. Ejecutamos una prueba de carga y logramos 17,000 solicitudes por segundo. Estamos utilizando Deno versión 1.10.3. Para usar 'hey', descárgalo del repositorio de GitHub y cambia el nombre del archivo. Importa 'serve' desde la biblioteca estándar de Deno para crear un servidor.

Muy bien, aquí estamos simplemente creando un servidor y luego lo usaremos para escuchar. Podemos hacer esperas en el nivel superior, lo cual es genial. Así que vamos a hacer un bucle 'for await'. Obtenemos la solicitud del servidor. Entonces, cada vez que se establece una conexión, obtendremos esa conexión y simplemente responderemos a ella. Así que podemos hacer request.respond y establecer un objeto, y también obtendrás tus tipos aquí. Así que simplemente pasamos un estado de 200 y haremos un cuerpo con 'hello world'. Sí, esto es genial.

Deno admite esperas en el nivel superior, lo cual es genial. Y también tiene soporte incorporado para generadores e iterables y eso es lo que estamos usando aquí. Sí, es genial. Normalmente, si estuvieras en Node o algo así, tendrías que crear una función asíncrona y luego hacer tu espera allí y llamarla desde el archivo principal. Pero Deno admite esperas en el nivel superior, así que no tenemos que hacer eso. Simplemente funciona, lo cual es genial.

Muy bien, eso debería ser todo para nuestro servidor. Este es nuestro servidor de biblioteca estándar, hello world. Solo estamos diciendo que vamos a escuchar en el puerto 3000. Vamos a obtener una solicitud. Cuando el servidor se siente aquí y espera a que llegue una conexión desde un navegador, cuando lo haga, pasará por este bucle. Tendremos una instancia de solicitud y luego simplemente responderemos con 200 y hello world. Así que no estamos haciendo nada muy complicado aquí, solo una implementación muy básica.

Ahora, si vamos a nuestra terminal, simplemente podemos decir deno run, luego tenemos que decir allow-net. Esa es otra característica de Deno, que está asegurado de forma predeterminada. Entonces, debes decirle a Deno a qué quieres permitir que tu programa tenga acceso. Así que estoy diciendo que quiero que tenga acceso a la red. Entonces, tienes allow-net, tienes allow-read para el sistema de archivos, write plugins. Hay algunas cosas diferentes de seguridad que necesitas aquí. También necesitamos activar la bandera de inestable. Así que voy a poner --unstable, y luego le daré el archivo. Así que biblioteca estándar, hello world, sí. Si ejecutamos eso, comenzará a ejecutarse y abriremos nuestro navegador, localhost 3000. Y ahí está nuestro hello world. No, probablemente no puedas verlo porque es muy pequeño. Permíteme, permíteme hacer zoom. Veamos y bueno, eso no es lo que quería hacer. No es el zoom correcto. No recuerdo el comando, oh ahí está. Muy bien, hello world. ¿Qué tal? Está funcionando. Es bastante rápido. Ahora ejecutemos una prueba de carga contra eso. Así que lo tengo ejecutándose. Voy a ir a otra ventana. Voy a ejecutar hey. Así que hago menos Z. Voy a hacer 10 segundos y le damos nuestra URL que es localhost 3000. Y lo que hará es ejecutar y golpeará ese servidor web tantas veces como pueda en 10 segundos. Y luego nos dará una salida de lo que sucedió. Ahí vamos. Subo un poco, lo tengo mucho ampliado así que no puedo verlo. Puedes ver que en realidad volvimos a ejecutar en 10 segundos ciento setenta mil solicitudes estábamos haciendo 17,000 solicitudes por segundo. Eso es realmente increíble, para ser honesto. Estamos ejecutando un servidor HTTP de TypeScript aquí. Quiero decir, eso es bastante impresionante lo rápido que es lo cual será aún más impresionante cuando hagamos los Hyperlinks pero eso es rápido. Así que esta es nuestra línea de base donde estamos tratando de ver 170 o 17,000 solicitudes por segundo. Muy bien. Puede que el tuyo sea diferente. Depende totalmente de tu hardware. Solo estoy en una MacBook Pro aquí. Sí, así que si tienes problemas tal vez revisa qué versión de Dino estás ejecutando. Estamos ejecutando o no sé qué está ejecutando Matt. Él puede verificar. Pero estoy ejecutando la versión 1.10.3 de Dino que es la última. Eso es en lo que estoy también. Si tienes Dino, solo ejecuta Dino upgrade y eso es todo. Irá automáticamente, obtendrá la última versión y la actualizará para ti. Si no tienes Dino, tendrás que descargarlo e instalarlo. Creo que hay como un comando curl que ejecutará un script de shell que lo descargará e instalará para ti. Sí, así que si quieres usar hey, en el repositorio de GitHub, tienen algunas descargas según tu sistema operativo. Pero para Mac. Si quieres usar hey, lo que hice, la razón por la que el mío es solo hey es que cambié el nombre del archivo cuando lo descargué. Es como hey_mac OS architecture. Lo renombré y lo copié en mi carpeta donde estamos. Y ejecuté, si ejecutas chmod 777 hey eso te permitirá ejecutar ese archivo. Y es posible que debas, si estás en un Mac, es posible que debas ir a la configuración y permitirlo, ve a la security. Porque Apple lo bloqueará porque descargaste un ejecutable de internet, lo cual es bueno, pero a veces inconveniente. Sí, es posible que debas hacerlo funcionar. Así que ahora puedo intentarlo. Sí, si estás obteniendo este requestAnimationFrame.respond, supongo que tienes... Sí, no es requestAnimationFrame.respond, es Req.respond en su lugar. Sí, aquí está el código nuevamente. Lo siento, probablemente no lo dejé el tiempo suficiente. Pero lo que estamos haciendo es importar serve desde la biblioteca estándar de Deno. Entonces, cuando importas de Deno, y solo haces barra, std, y luego el número de versión de la biblioteca estándar que deseas, hay muchas cosas que puedes poner en este nivel. Ahora estamos obteniendo HTTP. Hay cosas como para el sistema de archivos, la ruta, muchas cosas se ven muy similares a lo que podrías encontrar en Node. Y en el archivo solo estamos importando server, que es como una implementación de nivel superior de HTTP. Es por eso que es una implementación tan simple para que esto funcione.

4. Configuración y Ejecución de un Servidor Básico en Deno

Short description:

Creamos un servidor y lo usamos para escuchar. Deno admite esperas en el nivel superior y tiene soporte incorporado para generadores e iterables. Ejecutamos el servidor en el puerto 3000 y respondemos con un estado 200 y el cuerpo 'hello world'. Ejecutamos una prueba de carga y logramos 17,000 solicitudes por segundo. Estamos utilizando Deno versión 1.10.3. Para usar 'hey', descárgalo del repositorio de GitHub y cambia el nombre del archivo. Importa 'serve' desde la biblioteca estándar de Deno para crear un servidor.

Pero simplemente decimos, estamos creando una variable constante para nuestro servidor. Estamos diciéndole a la función serve que queremos ejecutar en el puerto 3000. Y luego simplemente, este bucle nos permite simplemente sentarnos y esperar eternamente a que lleguen solicitudes para que nunca se apague. Y cada vez que recibimos una solicitud, simplemente respondemos con hello world. Y lo que eso significa es que cualquier ruta a la que vaya, puedo simplemente escribir cualquier cosa aquí. Siempre vamos a obtener hello world como respuesta. Y por lo tanto, no hay enrutamiento.

Sí, entonces. ¿Qué pasa? No puedo ver las preguntas. Sí, solo estoy revisando algunas de ellas. Parece que puedes instalar hey a través de homebrew, así que eso es genial si lo tienes. Si estás en un Mac y tienes homebrew. La forma en que configuramos esta aplicación. Así que instalamos el complemento de VS code Deno, y luego puedes ver, sí, Matt puedes mostrar eso. 3.5.1. Sí, no es necesario. Si estás en un IDE diferente, es posible que tengas un complemento para ese IDE. Estamos usando VS code. Entonces, el siguiente paso que Matt tomó allí es que hizo un.VS code. Creo que hay un comando. Si haces Command Shift P o algo así, puedes inicializarlo. Sí, si haces Command Shift P, y escribes Deno, verás inicializar la configuración del espacio de trabajo. Eso creará el settings.json para ti. Lo que he encontrado, no sé qué es esto, algún tipo de error. Pero tengo que reiniciar VS code después de inicializar ese settings.json. De lo contrario, no toma en cuenta el hecho de que estoy en un espacio de trabajo de Deno. Y luego este es el código. ¿Alguna otra pregunta, Will, o podemos continuar?

Creo que eso es todo. Alguien tiene un problema con la caché, URL remota sin caché o faltante. Oh sí, entonces, ya tenía esta caché, así que no tengo el pequeño rizo amarillo, si tienes un rizo amarillo debajo de esto, no te preocupes, la primera vez que lo ejecutes, Deno lo descargará y lo cacheará. Así que eso es temporal. Sí, así que no te preocupes demasiado por el IDE, Deno seguirá funcionando, puedes ejecutarlo con el comando Deno. Sí, este, si no obtienes tipos, como si tuvieras una solicitud o algo así, y no ves una solicitud de servidor allí o, ya sabes, servidor y es solo como un any, entonces probablemente necesites reiniciar BS code. Pero si solo ves el rizo amarillo debajo de la importación, si es un rizo rojo, probablemente lo hayas escrito incorrectamente. Y luego escribe la ruta correcta. Pero si es amarillo, solo significa que Deno aún no lo ha caché, por lo que es posible que no tenga los tipos. Oh, eso es genial. También puedes hacer Command Shift P y ejecutar Deno restart language service y eso también funcionará. De acuerdo, genial. Sí, ahí mismo el servidor de lenguaje, ¿verdad? Sí, eso podría funcionar en lugar de reiniciar VS code. Sí, entonces John pregunta, ¿podemos agregar el script de inicio en un archivo como un package JSON? Supongo que sí, puedes hacerlo. Deno no tiene nada como un package JSON de forma predeterminada. Por lo tanto, no tiene ningún script ni nada. También podrías crear un archivo de script de shell y simplemente tener el comando allí y luego ejecutar el script de shell. Sí, puedes usar scripts de shell. Probablemente haya cosas de Dino que puedas instalar para admitir algún tipo de scripting. Estoy bastante seguro de que las hay. Creo que he visto algunas cosas que admiten scripting compatible con NPM. Pero. Es cierto, también puedes ejecutarlo directamente en VS code simplemente que también puedes usar, en realidad puedes usar NPM, lo cual tal vez haga eso rápidamente. Entonces podrías hacer, puedo crear un package json aquí. Sí, exactamente, podrías crear un package json y luego simplemente usarlo y ejecutar Dino en lugar de. En mi script diré que lo llamaré std. Sí, std. Sí. Estándar. Estándar, eso es lo que significa. Y luego, ¿qué era? Oh sí. Así que en realidad puedo usar npm aquí si quiero. Se siente mal porque estoy en Dino, pero ahora puedo hacer npm run std y estamos listos. Entonces James pregunta, o más bien dice, ejecuté hey, contra un pequeño servidor de mode JS y obtuve 14 solicitudes por segundo en comparación con las 11,000 solicitudes de Dino por segundo. Te gustaría saber si el bucle for tiene algo que ver. Es posible que podamos, tal vez tengamos tiempo para profundizar en esto más adelante, pero cuando ejecutas servidores web, cosas que parecen ser solo una línea de código, muy pequeñas, pueden tener un gran impacto en el número de solicitudes por segundo que tu servidor puede manejar. Incluso algo tan simple como una declaración de console log puede reducirlo mucho. Console log es mucho más costoso de lo que piensas. Por lo tanto, es posible que tengas un servidor node.js muy pequeño, y creo que fuera de la caja, el servidor DNode es ligeramente más rápido, pero a menos que sean idénticos, es difícil saber qué podría estar ralentizando uno en comparación con el otro. Otra pregunta, ya que estás dirigiendo el masterclass, ¿utilizas Dino en producción? Si es así, ¿para qué? En realidad, aún no he implementado Dino en producción, pero creo que Matt lo ha hecho. Sí, he creado algunos sitios pequeños con Dino, pero aún no he implementado nada con Hyper en producción, pero solo porque todavía está en un estado inestable, pero he utilizado la biblioteca estándar. Muy bien, ahora hagamos la parte interesante. Usemos Hyper. Es un poco más complicado, pero no es tan malo. Muy bien, puedes usar la biblioteca estándar. Esto es en realidad, quiero mostrarte una cosa más sobre las bibliotecas estándar. Creo que esto es interesante para que la gente lo vea. Oops. Muy bien, así que voy a la biblioteca estándar aquí. Estoy en HTTP. Veamos en server, y verás que esta es una implementación de TypeScript. Por lo tanto, está haciendo cosas como, cuál es el enlace de contenido y averiguándolo. Tiene que crear todos los encabezados, como los encabezados HTTP. Como esto está haciendo todo para admitir HTTP. Lo único que proviene de Deno que es nativo en este caso, es la conexión TCP. Por lo tanto, está utilizando Deno para obtener una conexión TCP para escuchar en el puerto que le indiquemos. Y una vez que se establece esa conexión TCP con el navegador, se la entrega a TypeScript y le dice, está bien, haz lo que quieras. Y TypeScript es responsable de leer el cuerpo, obtener los encabezados, establecer los encabezados cada vez que envías algo como el enlace de contenido aquí. Todas esas cosas se están manejando, se están gestionando en TypeScript, que es un lenguaje interpretado.

5. Usando Hyper para un Mejor Rendimiento

Short description:

Vamos a usar Hyper, una nueva API de Deno introducida en la versión 1.9, que es una implementación de HTTP en Rust. Está bien escrita y maneja los errores y el protocolo HTTP correctamente. Se recomienda NGINX para servir archivos estáticos debido a sus características adicionales como registros de acceso, proxy inverso y manejo de SSL. Crearemos una implementación de Hello World utilizando Hyper. Escucharemos las solicitudes TCP y utilizaremos la función 'respond with' de Deno para integrarnos con Hyper. La prueba de carga muestra que Hyper es aproximadamente un 35% más rápido que la implementación estándar en TypeScript de la biblioteca.

Por su naturaleza, no será tan rápido como un lenguaje nativo como Rust. Ahora vamos a usar Hyper, que es una nueva API de Deno introducida en la versión 1.9. Y puedo mostrarte Hyper también, antes de empezar. Alguien acaba de preguntar, ¿podemos usar deno.listen? Y vamos a llegar a eso ahora mismo. Estamos a punto de hacerlo. La respuesta es sí, puedes hacerlo. Sí, la respuesta es sí, deno.listen es lo que la biblioteca estándar hace internamente. Pero esto es Hyper, por lo que es una implementación en Rust de HTTP. Es muy popular por estar muy bien escrita, muy correcta, manejar los errores y el protocolo HTTP correctamente. Por eso estaba realmente emocionado de mostrar esto. Alguien preguntó si el servidor de deno es mejor para servir archivos estáticos que Node. ¿O deberíamos seguir usando algo como NGINX? Todavía usaría NGINX porque tiene muchos más casos de uso que simplemente servir archivos. Hay mucho más que puedes hacer con él. Y en general, es mejor ejecutar JS detrás de NGINX. Sí, no creo que obtendrías mucho beneficio de rendimiento con Hyper en frente de él. No creo que NGINX vaya a ser más rápido pero NGINX te ofrece más que simplemente servir archivos. Puede darte registros de acceso. Es un proxy inverso. Puede manejar SSL. Sí, puede encargarse del SSL por ti para que no tengas que preocuparte por eso. Sí, hay muchas cosas que maneja por ti. Muy bien, ahora he creado otra carpeta llamada hyper y vamos a crear una implementación de Hello World utilizando Hyper. Así que simplemente le daré el mismo nombre. Alguien preguntó, ¿puedes repetir lo que dijiste sobre standard y TypeScript? Mostraste algo de código y no lo entendí. Si te refieres al servidor estándar, puedo pegar algo de código, lo tengo. He abierto la biblioteca estándar. Sí. Eso fue solo para mostrarte que lo que estamos haciendo aquí, cuando importamos esto, estaba mostrando este archivo, este archivo server.ts. Cuando importamos esto, esto es en realidad solo TypeScript manejando HTTP. Por lo tanto, está haciendo todas las cosas para admitir HTTP y lo está haciendo en un lenguaje interpretado en un servidor. Simplemente inherentemente será más lento que tener código de máquina. Aunque sigue siendo muy rápido. Eso es lo sorprendente. Realmente muestra el poder del motor V8. Es tan eficiente en la ejecución de JavaScript. Muy bien. Construyamos el servidor Hyper. El momento que al menos estaba esperando. Muy bien. Lo que tenemos que hacer ahora es escuchar las solicitudes TCP. Entonces vamos a deno.listen, deno, deno. Estoy tan acostumbrado a decir deno. Pero han confirmado que es deno. Y para aquellos que no lo sepan o aún no se hayan dado cuenta, deno es simplemente node pero con una letra cambiada. Así es como, o dos letras supongo. Sí. Muy bien, sí, la misma persona que escribió node escribió deno. Solo corrigió algo que no le gustaba. Muy bien, lo que vamos a hacer ahora es otro await en el nivel superior. Será ligeramente diferente. Vamos a obtener la solicitud. Así que en este caso, cuando hacemos esto, esto es solo TCP. Por lo tanto, solo estamos obteniendo una conexión TCP. En este punto, aún no hay HTTP involucrado. Luego crearemos una función llamada handle HTTP. Y pasaremos esa conexión que obtenemos. Entonces, aquí abajo, vamos a crear una función asíncrona, vamos a llamarla handle HTTP. Y eso es de tipo dno.con, lo cual molesta a Will. Sí, no sé. Yo diría punto conexión, pero eso podría ser solo mi forma de pensar de Microsoft y pensar que todo necesita un nombre completo. Sí, tus nombres de función deben tener al menos 50 caracteres. Entonces lo que vamos a hacer ahora, esta es la nueva API que se agregó en la versión 1.9 de deno, y es deno.serve HTTP. Este es el punto de integración para Hyper. En este punto es cuando estamos usando Hyper. Por lo tanto, obtenemos nuestra conexión TCP de deno, y luego la pasamos a Hyper de esta manera, es una función. Pasamos la conexión y ahora, estamos desestructurando aquí y sacando la solicitud y respond with. La solicitud tiene todo, como los encabezados y, ya sabes, todas las demás cosas que vienen con la solicitud. Me gusta el cuerpo, la URL, todo eso. Y respond with es la función que podemos usar para enviar una respuesta a la solicitud. Así que simplemente llamaremos a respond with, y crearemos una nueva respuesta y pasaremos 'hello world'. Y ahí lo tienes. Esta es nuestra implementación de Hyper Hello World. En realidad no estamos usando la solicitud aquí, así que probablemente puedo sacarla. Muy bien, lo dejaré ahí por un segundo y luego lo ejecutaremos. Pero básicamente lo explicaré de nuevo. Creamos un oyente TCP, por lo que esto es simplemente el protocolo de red, el protocolo de Internet esperando una solicitud, cuando el navegador lo alcanza, primero establece una conexión TCP y una vez que se establece esa conexión, utilizará HTTP sobre TCP. HTTP es un protocolo de nivel superior que TCP. Se ejecuta sobre TCP y luego pasamos esa conexión a Deno, servimos HTTP y eso es lo que utiliza Hyper y luego simplemente respondemos con Hyper y creamos una nueva respuesta y pasamos 'hello world'. Vamos a ejecutar esto y ver qué tan rápido es. Así que voy a detener esto y haremos Deno run permitir opcionalmente net, inestable y esta vez haremos Hyper, hello world. Bien, estamos en marcha, asegurémonos de que esté funcionando, actualicemos, todo está bien y ahora hagamos una prueba de carga contra él. Usamos Hey, lo ejecutamos durante 10 segundos y ahora estamos obteniendo 257,000 solicitudes. Así que antes obtuvimos 170,000 solicitudes en 10 segundos, que eran aproximadamente 17,000 solicitudes por segundo y ahora estamos obteniendo 257,000 solicitudes en el transcurso de esos 10 segundos a 25,000 solicitudes por segundo. Por lo tanto, Hyper es aproximadamente un 35% más rápido. Eso es lo único que hicimos diferente de la biblioteca estándar, que es una implementación en TypeScript. Bastante impresionante. Quiero decir, eso es mucho más rápido. Estamos hablando de la utilización de recursos y la escalabilidad de una aplicación web muy eficiente. Es un gran avance. Muy bien. Mostraré el código una vez más.

6. APIs Inestables y Contribuciones a Rusty V8

Short description:

Utilizamos la API inestable de Sherift HTTP porque aún no se considera estable para producción. El equipo de Deno puede cambiar la interfaz de las nuevas APIs, por lo que quieren dejar en claro que el uso de APIs inestables conlleva riesgos. También han contribuido al proyecto Rusty V8, que proporciona enlaces de Rust para el motor V8, permitiendo que cualquiera use el motor V8 con Rust. Esta contribución demuestra su compromiso con la comunidad.

¿Hay alguna pregunta sobre esta parte? ¿Qué tenemos en el archivo A? Sí, estamos mostrando el código nuevamente. Alguien hizo la pregunta, ¿por qué usamos inestable? Correcto, esta API aquí, Sherift HTTP aún no se considera estable para su uso en producción por parte del equipo de Deno. Creo que está bastante cerca. Creo que para la versión 1.11, será estable, que lanzan con bastante frecuencia, creo que más de una vez al mes. Así que no esperaría que sea estable pronto, pero esa es la razón por la que usamos inestable. Por lo tanto, no tuvimos que usar inestable para la biblioteca estándar. Y eso es simplemente una forma explícita para que Deno diga cada vez que lanzan una nueva API que podrían cambiar la interfaz. Por lo tanto, no quieren que lo implementes en producción y luego, ya sabes, en la versión 1.11, cambien un poco la interfaz, tal vez respond with simplemente se convierta en respond o algo así. No quieren que despliegues eso. Al hacerte poner explícitamente inestable, es como si el equipo de Deno te dijera `oye, úsanos bajo tu propio riesgo`. Podríamos cambiar esta implementación ligeramente. Y podría romper algo si lo implementas en producción. Migrar algo así como si actualizaras Deno en producción sin cambiar tu código para tener en cuenta los cambios de interfaz que hicieron. Sí, pegaré el código aquí. Sí. Eso probablemente sea inteligente. Sí. Entonces, si tienes problemas, puedes verlo allí y pegarlo si lo necesitas. Muy bien. Bueno, ahora alguien dice, tomémonos un momento para agradecer a Ryan Dal. Absolutamente. Él creó Node, así que eso es suficiente para elogiarlo. Y ahora Deno, decidió hacerlo de nuevo. Y Deno es genial. Deno es increíble. Otra cosa que han hecho al crear Deno es realmente contribuir a V8. Quiero mostrar esto, es genial. Hay algo llamado Rusty V8. Y esto es mantenido por el equipo de Deno. Son enlaces de Rust para el motor V8. Así que ahora cualquiera puede usar el motor V8 con Rust simplemente usando estos enlaces, lo cual es genial. Parte del proyecto Deno fue que necesitaban, querían construirlo todo en Rust, por lo que necesitaban crear enlaces al motor V8 porque está escrito en C y C++. Por lo tanto, puedes crear enlaces de Rust para comunicarte con C y C++ y crearon todo esto, de código abierto, permitiendo a las personas usar ahora V8. Han contribuido mucho a la comunidad, lo cual me emociona mucho también.

7. Construyendo un Marco de Trabajo Web y Usando Hey

Short description:

Necesitamos manejar diferentes cosas en diferentes rutas. Es posible que deseemos registrar cada solicitud y ejecutar código específico para cada ruta. Estamos construyendo un marco de trabajo web llamado Hyperbole. Estamos usando Hey para estadísticas y pruebas. Instala Hey con Homebrew en Mac.

Muy bien, hemos creado este servidor web, es genial. Es bastante básico, supongo que podríamos usarlo en producción. Pero, quiero decir, por lo general, necesitamos tener diferentes cosas que sucedan en diferentes rutas y aquí es donde se complica.

Hasta ahora todo ha sido bastante sencillo, pero luego se complica porque ahora necesitamos decir, como, si estoy en una URL específica, si estoy en una ruta específica, quiero servir algo diferente a la página de inicio, a la barra diagonal o lo que sea, necesitamos manejar esos casos. Y también puede haber momentos en los que queramos hacer algo en cada solicitud. Por ejemplo, si queremos registrar cada solicitud, como crear un registro de acceso, necesitaríamos tener algún tipo de middleware que se ejecute en cada solicitud, tal vez medir la duración de esa solicitud y luego mostrarla, imprimirlo en la consola. Pero luego también queremos ejecutar este código específico para la ruta que realmente va a responder al servidor. Es posible que el middleware no responda al navegador con nada, pero es posible que desees hacerlo en una función diferente.

Entonces, lo que vamos a hacer, lo siento, esto es. Lo que vamos a hacer es construir un pequeño marco de trabajo web. Es el mejor marco de trabajo web que jamás haya existido y lo vas a construir y lo llamaremos Hyperbole. Espero que algunas personas hayan entendido mi chiste de papá allí. Para ver estas estadísticas, estamos usando Hey, así que lo he vinculado en el chat de Discord. Pero por ejemplo, el comando para Hey, solo para probar localhost sería hey-z con 10s. Eso ejecutará una prueba de 10 segundos para ver cuántas solicitudes puede hacer en 10 segundos. Entonces, si vas a ese repositorio de GitHub, ¿hay algunos enlaces de instalación para descargar el archivo Hey? Puedes agregarlo a tu ruta o lo que sea si quieres usarlo desde cualquier lugar. O simplemente colócalo en tu carpeta y llámalo como lo hace Matt. Sí, hice eso para no tener que agregarlo a mi ruta ni nada. También puedes instalarlo con Homebrew si estás en una Mac y tienes Homebrew. Homebrew, lo recomendaría porque entonces no, y estará en tu ruta. Solo puedes ejecutar, hey, estoy haciendo.slash hey porque no lo he agregado a mi ruta. Sí, es una herramienta pequeña y genial para probar tu código.

8. Construyendo el Marco de Trabajo Web Hyperbole

Short description:

Vamos a desarrollar Hyperbole, un marco de trabajo web construido alrededor de la implementación Hyper de Deno. Es el mejor marco de trabajo web de todos los tiempos. El más grande marco de trabajo web de todos los tiempos. Primero definiremos los tipos y luego implementaremos la función del servidor para obtener una instancia de un servidor que pueda escuchar en un puerto y crear rutas. El servidor tendrá una función de escucha que tomará un número de puerto y devolverá desconocido. La función 'all' permite crear rutas que respondan a cualquier método. Comenzaremos con una implementación básica y avanzaremos desde allí.

Muy bien, voy a detener Hyper. Hola mundo. Y vamos a comenzar a desarrollar Hyperbole nuestro marco de trabajo web construido alrededor de la implementación Hyper de Deno. Es el mejor marco de trabajo web de todos los tiempos. El más grande marco de trabajo web de todos los tiempos. Esto es hyperbole. Es verdaderamente, verdaderamente hyperbole.

Muy bien, por lo general, cuando comienzo a escribir algo como esto, quiero definir mis tipos primero. Eso me ayuda a prepararme mentalmente para lo que voy a desarrollar. Pero llegaremos a eso en un segundo. Pero lo que vamos a hacer, la implementación que va a suceder aquí es exportar una función llamada servidor. Y esto es lo que vamos a llamar para implementar, quiero decir, para obtener una instancia de un servidor que luego podemos usar para escuchar en un puerto y luego crear rutas a partir de él. Así que voy a crear otro archivo que importará esto, y luego te mostraré cómo queremos que funcione. Entonces, este servidor va a tener una función de escucha. Permíteme crear un tipo. Lo llamaré HyperServer. Así que estoy creando una interfaz de todas las funciones que queremos que estén aquí. Queremos 'escuchar', y eso va a ser una función que toma un puerto, que es un número, y devuelve un... Bueno, creo que hicimos un desconocido. Sí, solo devuelve desconocido para todos esos. Sí, y luego vamos a tener 'all', así que este es uno. En Express, 'all' te permite crear una ruta que escucha para métodos como get, post, delete, put. Y no importa cuál sea el método. Responderá a eso. Entonces, 'all' va a tomar una ruta. Tiene una cadena, así que sería como slash hello slash world. Esa será nuestra ruta. Y también necesita recibir una función que se ejecutará cada vez que se establezca una conexión que debe estar allí. Por ahora, no voy a completar esto todavía. Solo voy a poner algo en blanco. Muy bien. Vamos a hacer esto paso a paso porque es una cantidad decente de código que vamos a hacer.

9. Nombrando el Controlador y Limpiando el Código

Short description:

Necesitas nombrar la variable del controlador y hacer que devuelva desconocido. Elimina los dos puntos después de escuchar y todo y reemplázalos por un solo dos puntos. En la codificación en vivo, puede volverse loco, pero solo necesitas las funciones en la interfaz, así que usa dos puntos en lugar de un signo igual. Es solo semántica, pero probablemente sea más limpio.

Sí, ¿necesitas darle un nombre, verdad? Como controlador dos puntos. En realidad, tengo que convertirlo en una variable. Sí. Entonces este es nuestro controlador y va a devolver desconocido. ¿Qué hice mal aquí? Espera. ¿Por qué no funcionó eso? Porque tienes, tienes escuchar dos puntos. Escuchar dos puntos y todo dos puntos y todo lo que realmente necesitas es escuchar y luego dos puntos en lugar de la flecha gruesa al final. Oh, no hice la flecha gruesa. Porque estás haciendo una interfaz aquí, ¿verdad? Cuando estás codificando en vivo, hombre, es como una locura. Tienes una interfaz con propiedades pero realmente solo necesitas que sean funciones, ¿sabes a lo que me refiero? Sí, quiero decir, simplemente hago eso. Sí, y luego pon dos puntos al final en lugar del igual. Correcto, sí. Hombre, igual. Es semántica. Es semántica. Sí. Pero sí, probablemente sea más limpio, diría yo.

10. Creando un Servidor Básico y un Controlador

Short description:

Estamos creando un servidor básico con un controlador para middleware. La función devolverá un servidor liberado de Hyper. Crearemos funciones para escuchar, todo y usar. En este caso, no es necesario usar una clase, ya que la función del servidor solo se llamará una vez. Es solo una preferencia. Se utilizará una clase en otra área más adelante.

Otra cosa que vamos a hacer es usar. Así que en este caso no vamos a tener una ruta, solo vamos a tener un controlador. Y esto es lo que usaríamos para nuestro middleware. No voy a definir qué es un controlador en este momento, pero por ahora vamos a crear un servidor muy, muy básico para poder iterar sobre esto. Muy bien, ahora esta función va a devolver un servidor liberado de Hyper. Así que necesitamos crear algunas funciones aquí para que lo devuelva, así que crearemos una función de escucha. Está en un puerto, un número, y va a, no lo haré por ahora. Y el todo, así que solo voy a crear todas estas que creamos allá arriba. Y tendremos que refactorizar algo de esto, pero, así que, y uso. Sí, y si estás familiarizado con Express, esto puede parecer algo similar a cómo opera Express. Correcto. Luego vamos a devolver esto, como todo, escucha y uso. Así que solo estamos tratando de configurar esto en este punto. ¿Hay alguna razón por la que no estás usando una clase aquí? No hay ninguna razón para no usar una clase aquí, pero Matt decidió no usarla. Podrías usar una clase o podrías usar una función. En este caso, no importa demasiado porque no estarás llamando a esta función del servidor muchas veces. La llamarás una vez, así que incluso si creas una clase, solo tendrías una instancia singleton de esa clase. Entonces no obtendrías todas las ventajas que obtienes con las clases, con los prototipos y todo eso. Pero en este caso, no hace mucha diferencia si usas una clase o usas funciones como Matt ha definido aquí. Sí, es solo una preferencia en este momento. Vamos a usar una clase en otra área más adelante.

11. Implementando la Función de Escucha y Creando Controladores

Short description:

Comenzamos implementando la función de escucha y la dividimos en funciones más pequeñas para una mejor organización del código. Creamos la función waitForConnection para manejar el proceso de Deno.listen y la función handleHTTP para servir conexiones HTTP. Explicamos el concepto de for await y su uso con iterables asíncronos. Probamos la funcionalidad básica del servidor y observamos la velocidad de respuesta. Ahora nos enfocamos en definir los controladores y discutimos la opción de usar clases en la implementación del servidor.

Muy bien, ahora necesitamos comenzar a implementar esto. Lo principal en lo que queremos trabajar inicialmente es nuestra función de escucha. Así que intentemos llegar al punto en el que tengamos un 'Hola Mundo' en cada ruta de nuestro servidor, y luego comenzaremos a descomponerlo a partir de ahí.

Muy bien, nuestro servidor realmente necesita hacer un Deno.listen. Así que vamos a dividir esto en más funciones solo para hacer nuestro código un poco más limpio. Entonces, una de las funciones que queremos es waitForConnection, y esto hará el Deno.listen. Y haremos un listener, y luego obtendremos el puerto aquí también. Muy bien. Y luego tenemos que hacer un for await, vamos a obtener esa conexión del listener, y luego aquí vamos a descomponer esto en, ¿cómo lo llamamos? Solo quiero asegurarme de que eso esté correcto. No, lo llamamos handleHTTP. Sí, eso es lo que pensé, pero solo quería, handleHTTP, y luego simplemente pasamos esa conexión. Solo estamos haciendo esto para dividir nuestro código, no me gusta tener funciones grandes con toneladas de código en ellas. Así que ahora vamos a crear la función handleHTTP. Y tomará una conexión, digamos dino.con, y luego en realidad hará el serveHttp. Así que obtendremos una conexión HTTP, serveHttp y pasaremos la conexión, y luego necesitamos un bucle para esto, así que for await. Y esta vez necesitamos una solicitud y una respuesta porque vamos a usar ambas. Con, responder con. No, con. Eso es gracioso. Y luego, sí, ahora lo que vamos a hacer es crear otro que es process, bueno, ahora mismo solo vamos a responder, solo vamos a responder por ahora, solo para que esto funcione y podemos crear algún otro código. Entonces, esto no es cómo se verá para siempre, pero queremos que nuestro hyperbole funcione antes de escribir cientos de líneas de código. No, no estamos escribiendo cientos de líneas de código. Así, ¿está bien? Ahora dibuja el resto del Búho. ¿Está bien de tamaño para todos? ¿Puedes leerlo bien? Sí, puedo leerlo bien. Lo hice un poco más pequeño para que pueda caber más en la pantalla. El tamaño está bien. Genial. Bien, ahora en nuestra función de escucha, lo que vamos a hacer es llamar a waitForConnection con el puerto. ¿Verdad? Oh, waitForConnection. ¿Quieres hacer dino.listen, verdad? Tengo eso aquí arriba, lo tengo en waitForConnection. Oh, okay, bien, bien. Supongo que está bien, ¿verdad? Sí, en realidad no necesariamente necesitas waitForConnection, puedes poner ese código en cualquier lugar. Pero es bueno tener una buena interfaz alrededor de tu función de escucha para que publiques eso y eso es lo que usa el usuario de tu biblioteca y luego haces internamente lo que necesites. Correcto. Sí. Así que esto debería funcionar ahora. Bueno, aún no hemos implementado todo en uso, pero realmente no necesitamos hacerlo todavía. Solo vamos a escuchar y luego va a devolver todo. Así que voy a crear un archivo en la raíz aquí llamado server.ts y este será nuestro servidor que usa hyper-ability. Entonces vamos a importar server desde hyper-ability. index.ts porque estamos en Deno. Y luego simplemente podemos decir server.listen. Alguien está preguntando qué es el for await. Entonces, for await es un concepto en, existe en TypeScript y en el mundo de node también. Y en Deno, es un ciudadano de primera clase, pero siempre que tienes un iterable, un iterable es como un array o algo que publica un array de promesas o cualquier cosa que produzca. Se llama iterable y puedes hacer for await y simplemente esperará la siguiente iteración de lo que estás esperando. Muy bien, tengo los puntos aquí en MDM si quieres echarle un vistazo, así tienes iterables asíncronos y eso es lo que estamos usando aquí. Básicamente, lo que está sucediendo aquí es que esto está creando un objeto que solo espera conexiones. Simplemente está esperando de forma asíncrona a que un navegador lo alcance y cuando lo hace, este bucle for await se activa y crea, extrae esa conexión de aquí en otro objeto, que estamos desestructurando y luego podemos usar eso para responder a esa solicitud. Queremos asegurarnos de responder a estas solicitudes correctas de forma asíncrona, por eso en nuestro handleHTTP, ya sabes, porque no quieres que solo pueda responder a una solicitud a la vez esencialmente. Y sí, esos son no bloqueantes. Por lo tanto, puede haber otro código ejecutándose en otro lugar mientras esperas aquí, no está bloqueando toda la ejecución de otro código. Correcto. Muy bien, creamos esto y luego en nuestro server.ts, en realidad vamos a usar nuestro servidor. Entonces importamos nuestro servidor, ejecutamos la función. Hey, buen punto. Creo que tu función waitForConnection necesita ser asíncrona para que, para que funcione de esa manera. Sí, línea ocho. Haz que sea una función asíncrona. Y luego, ¿dónde está esto, está aquí, hagámoslo dos. No, este necesita dos. Sí. Así que ahora solo vamos a responder a 'Hola Mundo' pero eso no es lo que vamos a hacer. Solo queremos asegurarnos de que nuestro código funcione. No quieres codificar demasiado antes de probarlo. Así que probémoslo y asegurémonos de que funcione. Entonces, dino run allow-net. Voy a agregar dash dash watch aquí, lo que me permitirá, cada vez que mi archivo cambie, Dino se reiniciará y lo cargará para que no tenga que seguir viniendo aquí y ejecutándolo cada vez. Y ahora ha pasado este server.ts y ahora si vamos a nuestro navegador, deberíamos obtener el mismo resultado. Muy bien, lo estamos obteniendo. Incluso podríamos ejecutar una prueba de carga contra eso para ver cómo responde esto. Debería ser similar al de Hyper. En realidad, debería ser exactamente igual. Algo similar. Sí, estamos en 25,000 solicitudes por segundo, que es lo que estábamos obteniendo con Hyper. Ahora, a medida que implementamos esto, verás que este número disminuirá con el tiempo y hablaremos de eso. Muy bien, ahora tenemos un servidor básico. Está en funcionamiento. Ahora vamos a definir cómo queremos que funcione. Entonces, estos controladores, necesitamos poder agregar un controlador. Así que si vamos a nuestro server.ts, lo que quiero poder hacer es poder decir server.allon-slash. Ya hay una implementación de clase de este servidor ya vinculada en el chat aquí, así que a algunas personas les gustan más las clases que eso. A algunas personas todavía les gustan las clases. Sí, he estado usando React durante tanto tiempo que simplemente pensé que a nadie le gustaban las clases. Así que por eso lo hice una función. Bueno, pensaste mal. Pensé mal. La gente quiere clases.

12. Implementando las Funciones de Solicitud, Respuesta y Siguiente

Short description:

Estamos implementando las funciones de solicitud, respuesta y siguiente en nuestro marco Hyperbole. Creamos una clase HyperboleRequest, una clase HyperboleNext y una clase HyperboleResponse. La clase Response toma el tipo de evento Deno.request. Agregamos una función send a la clase Response para enviar una respuesta con un cuerpo, estado y encabezados. Agregamos campos al objeto Request para URL, cuerpo, método y nombre de ruta. También creamos un array de controladores de solicitud para realizar un seguimiento de los controladores configurados para la aplicación.

La gente ha hablado. Pero eso es bueno porque pronto implementaremos otra clase. Sí, así que ahora, si usas Express, lo que estás acostumbrado a hacer es solicitud, respuesta y siguiente, ¿verdad? Necesitamos que esto funcione. Necesitamos poder obtener una solicitud, una respuesta y una función siguiente y decidir qué hacer en nuestro... En todo, y queremos poder decir responder.punto enviar hola mundo. Idealmente, así es como se vería nuestra interfaz. Esto no funciona porque aún no lo hemos implementado, pero así es como queremos que funcione.

Y a veces me gusta pensar en cuando estoy codificando un marco o algo así. Me gusta ver cómo será la experiencia del desarrollador. Y lo descubro antes de comenzar a codificar el marco porque probablemente no terminaré donde quiero estar si no me enfoco realmente en la implementación o la interfaz que el desarrollador va a usar. Así es como quiero que funcione. Ahora hagamos que esto funcione realmente. Eso significa que necesitamos una solicitud, una respuesta y una función siguiente. Así que voy a volver a nuestro Hyperbole. Y estamos poniendo todo esto en un solo archivo probablemente quieras hacer algo diferente. Pero vamos a crear una clase HyperboleRequest. Vamos a crear una clase HyperboleNext. Y luego, para la respuesta, en realidad será una clase. Entonces vamos a decir, para la clase HyperboleResponse, no vamos a, la razón por la que vamos a usar la clase aún no será evidente, pero lo será en un momento. Muy bien. Así que veamos aquí. De acuerdo, para la respuesta, voy a crear un campo público, propiedad de campo, cualquier término que quieras usar. Necesitamos un constructor y en el constructor, necesitamos pasar respond-with ya que necesitamos poder usar esto para responder en los servidores. Así que solo estoy poniendo el tipo aquí. Puedo pegarlo en lugar de que tengas que escribirlo. Es mucho escribir. Y esto es literalmente solo copiar lo que realmente es respond-with. Muy bien. ¿Obtuve el número correcto? Demasiados, ahí vamos. Muy bien. Y luego aquí, simplemente lo llamamos Super. Eso es todo. No necesitas Super porque aún no has extendido nada. Oh, sí. Sí, veo que me estoy adelantando. Muy bien. Sí, definitivamente puedes usar eso en su lugar. Deno solicitud responde con, eso también funciona. Dilo de nuevo. Puedes usar el tipo específico de Deno, ¿verdad? Entonces, si solo haces Deno.solicitud evento, tiene la función respond-with en él así que puedes usar eso. Entonces, si solo usas Deno.solicitud evento, tiene la función respond-with en él así que puedes usar eso como tipo en. Modificaré mi respuesta para incluir eso. No creo que pueda hacer solo evento de solicitud aquí. Sí, puedes. Y luego necesitas un corchete abierto y respond-with entre comillas. No, corchete corchete. Corchete. Sí, y luego respond-with entre comillas. Entendido. Muy bien, eso es un poco más limpio. Muy bien, esta es nuestra respuesta. Entonces, lo que estamos haciendo aquí es cuando creamos nuestra respuesta, necesitamos pasar respond-with para que luego quien use nuestra respuesta pueda, lo que sea, ya sabes, cada vez que llamemos a send, lo que haremos ahora. Necesitamos send como una función. Y vamos a tomar un cuerpo, un estado, y encabezados. Muy bien. Y luego vamos a establecer nuestro estado igual a estado o 200 si no pasan uno. Y luego vamos a decir this.respond con una nueva respuesta. Que tomará nuestro cuerpo, y también nuestro estado, y nuestros encabezados. Muy bien, eso es todo lo que necesitamos por ahora. Ahora deberíamos poder llamar a response.send, pero aún no estamos haciendo ninguna ruta. Correcto, y eso es lo que tenemos que implementar ahora. Así que agreguemos algunos campos a nuestro objeto de solicitud porque vamos a comenzar a implementarlos ahora. Y lo que necesitamos hacer es comenzar a crear un objeto porque vamos a comenzar a implementarlos ahora. Para nuestra solicitud, queremos obtener la URL y la haremos de tipo URL con el navegador. Queremos poder obtener el cuerpo de la solicitud, por lo que es desconocido en caso de que sea un objeto, por lo que podría ser un JavaScript, como un objeto JSON que podemos formatear para ti. Obtendremos el método. Así que obtendremos post, actualizar, eliminar y el nombre de ruta. Ahora, solo será parte de la URL, que es la barra diagonal lo que sea, y lo usaremos para hacer algunas coincidencias. Y luego, para nuestra función siguiente, hagamos que esto sea solo un tipo. Diremos, exportar tipo hyperbole next. Siguiente, y será simplemente desconocido. Muy bien, ahora lo que vamos a hacer es, en lugar de hacer respond-with aquí, necesitamos comenzar a, necesitamos llamar a algunos controladores. Entonces, cada vez que, aquí, cuando estamos creando este server.all, estamos pasando una ruta. Necesitamos tener alguna forma de realizar un seguimiento de todos los controladores que se han configurado para la aplicación. Entonces, lo que vamos a hacer es, en nuestro código en el servidor, necesitamos tener un array que realizará un seguimiento de esto. Solo quiero asegurarme de hacer bien el tipado. Muy bien, creamos una constante de controladores de solicitud. Y será un array. Y vamos a tener una ruta aquí, que es una cadena. Y luego vamos a tener un controlador, que aún no hemos creado. Entonces, hagamos eso primero. Necesito crear una interfaz para eso. Entonces, mi controlador de solicitudes permanentes. Y esto será una función. Veamos. Creo que podría ser solo un tipo. Sí, lo haré un tipo. Podría ser una interfaz, pero lo haremos tipo. Y será exactamente lo que teníamos. Queremos tener solicitudes, que es una solicitud de Hyperbole.

13. Configurando los Controladores y Encadenando Llamadas

Short description:

Queremos configurar un controlador para la solicitud de Hyperbole. Agregamos el controlador a un array que realiza un seguimiento de todos nuestros controladores. Si usamos 'all', ejecutamos el controlador para cada ruta. Podemos crear una variable de servidor que incluya todos los métodos listen y use, y devolverla desde el use, all y listen. Esto permite encadenar llamadas.

Queremos que tenga una respuesta. Respuesta de Hyperbole. Y queremos que tenga una función siguiente, que es HyperboleNext. Y eso va a devolver, ¿qué era? ¿Desconocido, de nuevo? Sí. Muy bien. Esta es la definición de tipo para el controlador que tenemos aquí. Ahora estamos configurando esto. Muy bien. Si bajamos aquí, aquí está nuestro array. Nuestro controlador será del tipo HyperboleRequestHandler. Y esto simplemente será un array al que podemos agregar a medida que los obtenemos. Muy bien. Entonces, cada vez que llamemos a server.all o server.use, necesitamos agregar ese controlador que se pasa aquí a nuestro array que realiza un seguimiento de todos nuestros controladores. Así que si vamos a all, queremos cambiar esto de esta cosa temporal a nuestro controlador de solicitud de Hyperbole. Y queremos hacer requestHandlers.push, nuestra ruta y nuestro controlador. Muy bien, y para use, queremos que esto sea nuestro controlador de solicitud de Hyperbole también. Y lo que haremos aquí es en lugar de simplemente agregar dos controladores de solicitud, en realidad podemos llamar a this.dot o simplemente llamar a all y pasaremos un asterisco aquí, lo que significa que se ejecutará para todo. Y luego nuestro controlador. Te vi escribir this.dot, eso es lo que harías si hubieras comenzado esto como una clase. Mira, lo aprecio. Sí, es muy, no sabía, pensé que me regañarían por usar clases, así que pensé, no voy a usar clases. Y ahora todos quieren clases. Muy bien. Me gustan las clases, son geniales. Muy bien, nuestro use está diciendo, hey, queremos ejecutar esto para cada ruta. Así que tenemos que asegurarnos de que cuando decidamos qué controladores ejecutar busquemos el asterisco que indica que se ejecutará para todo. Entonces, otra cosa que podría ser útil hacer aquí es crear una variable de servidor que incluya todos los métodos listen y use y luego devolverla desde el use, el all y el listen. Y de esa manera, puedes encadenar tus llamadas. Claro, sí, tiene sentido. Entonces, lo devolveremos desde aquí. Moveré esto hacia arriba, porque es un poco extraño tenerlo debajo. Y se elevará, pero ya sabes. Bien, así que devolveremos el servidor aquí y devolveremos el servidor. Sí, ahí, y luego también en listen. De acuerdo. Sí, de esa manera podemos hacer algo como use.punto loquesea.punto loquesea. Sí, a veces se ve eso en el mundo de Express.

14. Implementando la Lógica de Manejo de Solicitudes

Short description:

Ahora necesitamos agregar lógica para determinar qué controlador llamar. Recorremos los controladores y verificamos si la ruta coincide. Si la ruta es un comodín, ejecutamos el controlador. Si no lo es, verificamos si la ruta de la URL coincide con la ruta de la solicitud. Finalmente, llamamos al controlador. Para procesar la solicitud, creamos una función llamada processRequest que toma una solicitud y una respuesta. Instanciamos la respuesta y creamos una función de solicitud de hyperbole para crear el objeto de solicitud. Luego llamamos a processRequest con la solicitud y respuesta instanciadas. ¡Es así de fácil escribir un marco web!

Muy bien, ahora lo que necesitamos hacer es cada vez que estamos manejando HTTP aquí, esto tiene que volverse un poco más complejo porque no podemos simplemente responder con hola mundo. Necesitamos ejecutar el controlador correspondiente. Así que vamos a implementar ese código y todo esto funcionará. Déjame ver aquí.

Muy bien, vamos a crear una nueva función llamada processRequest que handleHTTP va a llamar. Y debe ser asíncrona. ProcessRequest, y esto va a tomar un hyperboleRequest. Y un hyperboleResponse. No va a tomar una función net y verás por qué cuando lleguemos a las piezas de middleware. Así que verás por qué.

Muy bien, vamos a obtener una solicitud y una respuesta aquí y ahora necesitamos comenzar a agregar algo de lógica sobre qué controlador llamar realmente. Entonces, una cosa que vamos a hacer, voy a obtener, supongo que no lo haré al principio, mostraré qué sucede si no lo hacemos. Así que simplemente vamos a recorrer todos los controladores. Sí, estos no son los controladores de solicitud así que lo guardaremos. Y ahora solo necesitamos verificar la ruta para ver si coincide con lo que hay en las solicitudes. Entonces podemos decir, si rh.path, si es igual a asterisco, queremos hacer esto de todos modos, sin importar qué, así que lo agregaremos primero. Si la ruta en el controlador de solicitud es un comodín, simplemente decimos, vamos a ejecutar este controlador. Sí, y eso funcionará si usas dot use, o si lo llamaras dot all, entonces la ruta y el asterisco son tu ruta. Luego, queremos verificar la ruta y ver si coincide. Si no es una ruta para todos, queremos decir, ¿esta URL coincide con el nombre de la ruta de la solicitud que llegó? Así que recuerda que esta solicitud, vamos a tener que instanciarla o crearla. Supongo que no se está instanciando, ya que no lo hice una clase, pero vamos a crear esta solicitud y pasarla aquí. Muy bien, básicamente estamos diciendo, si la ruta en el controlador de solicitud coincide con la ruta en las solicitudes que han llegado, entonces también queremos ejecutar este controlador. Muy bien, ahora vamos a obtener el controlador de nuestro controlador de solicitud y luego queremos llamarlo. Así que simplemente diremos, esperar, controlador. Y para la próxima función, solo voy a inventar algo por ahora. Sí. Muy bien, esto debería ser suficiente en este punto para hacer algo que funcione. Solo necesitamos llamar, en lugar de responder aquí mismo en nuestro handleHTTP, queremos llamar a processRequest, pero necesitamos instanciar la solicitud y la respuesta. Entonces lo que vamos a hacer es crear una función. Para la respuesta, ya la tenemos, así que podemos hacer eso. Const respuesta igual a new hyperboleResponse, y pasamos respondwith. Así que eso está bien. Lo tenemos. Y ahora necesitamos crear la solicitud. Así que se verá así. Sí, solo haz una función para eso. Ahora vamos a ir más cerca de donde lo definimos. Definido. Aquí está, y simplemente crearemos una función. No necesita ser asíncrona. La llamaremos hyperboleRequest. Y si quieres convertir esto en una clase, adelante. Y vamos a pasar la solicitud, que tipo es ese? Solicitud. Oh, sí. Es solo solicitud en mayúscula. Sí, es la del navegador. Y luego vamos a devolver nuestra URL, así que queremos crearla aquí. Consurl igual a new URL. Vamos a solicitar esa URL. Entonces, la solicitud.url llega como una cadena, y queremos que sea un poco más agradable para las personas que están usando nuestro servidor, donde no es solo una cadena, sino un objeto en realidad. No querías crear el cuerpo aquí. Solo sin cuerpo por ahora. Sí, solo crearé. Crearé una variable de cuerpo por ahora que sea simplemente nada, pero tendremos que procesar eso más adelante. El método está en la solicitud, así que podemos decir solicitud.method y extraerlo. Y luego podemos obtener el nombre de la ruta de la URL. Entonces ahora podemos decir URL.pathName, y eso es solo un ayudante para nosotros. Podríamos hacer solicitud.url.pathName, pero solo lo estamos subiendo un poco. Muy bien, ahora donde estamos procesando la solicitud, necesitamos pasar, no REQ, sino solicitud, y deberíamos estar bien. Genial. Es así de simple. Sí, es tan fácil. Es tan fácil escribir un marco web. Quiero decir, ¿por qué no lo hace todo el mundo? Muy bien, veamos. No está tomando mi escritura, así que voy a hacer el, reiniciar el servidor de lenguaje. Ahí vamos. No le gusta que no esté usando la solicitud, necesitas poner guiones bajos allí, está bien. Ups, en realidad no cambié. Pensé que lo había cambiado, en realidad. No lo está captando. Permíteme reiniciar el servidor de TypeScript. Tienes que cambiar la interfaz porque está devolviendo una interfaz. Así que asegúrate de eso. No lo cambié. Sí. Oh, sí, sí, sí. Tengo que cambiar esto. Hm-mm. ¿Cómo funciona incluso? Todavía no lo está captando. Me pasó lo mismo el otro día también. Intentaré reiniciar los servidores ahora. Ups. Muy bien, genial. Está ahí. Tengo un problema. Veamos qué es. No estoy seguro de qué está quejándose aquí. ¿Los martillos son incompatibles? Sube. ¿A dónde quieres ir? Comienza en la interfaz.

15. Desarrollando un Router con Hyperbole en Deno

Short description:

Cambiamos el servidor para devolver la interfaz del servidor Hyperbole en lugar de 'unknown'. Encontramos algunos problemas de compatibilidad con la función 'use', pero los resolvimos. Agregamos un bloque try-catch para manejar posibles errores en el controlador. Si no se encuentra ningún controlador, enviamos una respuesta 404. Discutimos la importancia de la función 'next' para manejar múltiples funciones de middleware. La próxima parte será más desafiante. Pausamos para permitir que todos se pongan al día y respondan preguntas. La bandera 'handle true' indica que la solicitud ha sido manejada por una función de middleware. Enviar una respuesta 404 evita las fugas de memoria. La función 'next' permite llamar a otros controladores.

¿Cuál es la interfaz para el servidor? Así que cambia tu servidor para devolver la interfaz del servidor Hyperbole. En lugar de devolver 'unknown', devuelve el servidor Hyperbole en todos esos casos. Así que empecemos con eso. Hasta ahora lo hemos estado haciendo de esta manera antes. Sí, bueno, simplemente comenzaremos con eso. Solo para ponerlo al día con lo que estamos haciendo aquí. Y todavía no le gusta. Y luego la función 'use' es incompatible. Sí, así que ve a tu función 'use'. No puse el controlador aquí. ¡Ups! Ahí lo tienes. Quiero volver a 'unknown'. Oh, bueno, pondría 'server' allí, tiene sentido porque eso es lo que estás haciendo. Estás devolviendo el servidor Hyperbole. Hay una pregunta que dice, ¿puedes mostrar el 'hyperbole request' una vez más? Ah, sí. Así que básicamente tenemos una función aquí a la que le pasamos la solicitud de Deno desde el 'serve HTTP', cada vez que recibimos esa solicitud y luego queremos hacer algo con ella para que sea más utilizable para los usuarios. Envolverla. Así que obtenemos la URL, vamos a procesar el cuerpo y un poco más. Obtenemos el método y el nombre de la ruta. Muy bien. De acuerdo. Bueno, si quieres copiar eso en el chat. Sí. Así que tengo el código. Puede que sea demasiado largo para pegarlo en Discord, pero lo intentaré. Definitivamente es demasiado largo para pegarlo. De acuerdo. Ahora nuestro servidor está en funcionamiento. Veamos si esto funciona ahora. De acuerdo. Hemos estado ejecutándolo aquí porque hemos estado observando. Así que simplemente debemos ir a actualizar. Y está funcionando. De acuerdo, así que hicimos, ¿hacemos barra diagonal? Creo que sí. Sí, así que hicimos barra diagonal. Ahora, si voy a otra URL que no sea la de inicio, simplemente se quedará colgado. No está sucediendo nada aquí. Puedes ver que mi navegador se queda colgado, ves una pequeña línea azul. La razón es que lo que sucede, vamos a nuestro servidor y vamos a procesar la solicitud. No encontramos un controlador porque no tenemos nada para la ruta que puse. Y así recorre todos los controladores y dice, no tengo ninguno. Y solo me quedo esperando. No tenemos nada para decirle al servidor que debe enviar un 404. Así que simplemente se queda colgado para siempre, lo cual no es ideal. No es bueno, para nada bueno. Entonces lo que vamos a hacer es cambiar un poco este proceso de solicitud. Y simplemente vamos a crear un let 'handled' igual a 'false'. Y cuando llamemos a nuestro, cuando hagamos este bucle, lo envolveremos en un bloque try-catch. Por si acaso, como si el controlador fallara. No queremos que se bloquee todo. Realmente no nos importa necesariamente cuál es el error, aunque lo pondremos aquí. Y luego, después de llamar al controlador aquí, queremos establecer 'handled' en 'true'. Y luego, debajo de aquí, diremos si no se ha manejado, queremos hacer una respuesta que esté en, pasar 'undefined' para el cuerpo, porque no vamos a pasar el cuerpo, pero vamos a pasar 404 para el estado. Así que ahora, si hacemos una solicitud para la cual no tenemos un, no tenemos un controlador, eso hará una respuesta. Pasará por aquí. Lo manejará. Se mantendrá en 'false'. Así que cuando terminemos el bucle, simplemente responderemos con 404. Así que volvamos al navegador. Lo probaremos y verás que volvió de inmediato. Y si miramos la red, deberíamos ver un 404 ahora. Ahí está. Y si vuelvo a la página de inicio, debería seguir funcionando. Tenemos un enrutador. Hace algo. ¿Alguna pregunta hasta ahora? Parece ser una parte crítica. Hasta ahora, lo que hemos hecho es que solo podemos manejar uno. Solo podemos manejar un controlador a la vez. Porque no estamos implementando esa función 'next'. Así que necesitamos, esto va a tener que volverse un poco. Confuso, supongo, para entenderlo. ¿Hay alguna pregunta, Will, estamos bien? Parece que estamos bien. Estoy tratando de responder a medida que van llegando, pero puse el código hasta ahora en mi index.ts. Sí, si solo quieres el 'hyperbole next', ese es el tipo para eso. Tomaremos un breve momento para pausar y poner a todos al día. Sí, tanto como podamos. Voy a ir al baño y a buscar más agua rápidamente, porque esta próxima parte va a ser... Entonces, hay una pregunta, ¿Deberíamos romper el bucle 'for' cuando se usa un controlador, lo que significa que 'handled' es 'true'? Así que vamos a entrar en esto en un segundo, pero si piensas en si alguna vez has escrito un servidor express, puedes tener múltiples funciones de middleware que responden a la solicitud. Así que no queremos limitarlo a un solo controlador. Ahora, no estamos construyendo todo Express hoy, pero llegaremos a esta parte. La forma general en que funciona es cuando creas una función de middleware en Express y lo mismo con Hyperbole, tendrás que tomar una decisión. Puedes hacer algo con el objeto de solicitud o respuesta y luego llamar a la función 'next', lo que significaría pasar al siguiente middleware. O puedes terminar la solicitud, lo que significa que envías una respuesta. Si envías una respuesta, entonces no queremos llamar a ningún otro controlador. Pero si llamas a la función 'next', queremos poder llamar a otros controladores. Entonces lo que significa ese 'handled true' es que asumimos que si se llama a cualquier middleware, estás manejando esta solicitud. Así que si al final del día, no coincidimos con ninguna función de middleware, enviaremos un 404, pero si coincidimos con una sola, entonces asumimos que la has manejado. Y como dijo Matt, la razón por la que estamos haciendo ese 'handle true' y enviando el 404 en caso contrario es porque de lo contrario podríamos tener conexiones que se mantienen en memoria y podríamos tener una fuga de memoria y en realidad, lo que el servidor Deno intentará hacer es reutilizar la conexión, pero no puede reutilizar una conexión que ya tiene algún código en ejecución. Así que obtendrás un error.

16. Procesando Cuerpos de Solicitud y Agregando Respuesta JSON

Short description:

Agregamos una ruta para '/hello' que responde con 'world'. Discutimos la importancia de las pruebas de carga para garantizar el rendimiento del framework. Introducimos el concepto de procesar los cuerpos de las solicitudes y agregar una función de respuesta JSON al objeto de respuesta. Explicamos la necesidad de analizar el cuerpo de una solicitud y demostramos cómo hacerlo utilizando el decodificador de texto. Mencionamos el impacto en el rendimiento de crear la variable URL y los beneficios de crear una interfaz más accesible en el framework. Concluimos agregando un registro como una mejora futura.

Entonces, handled true, no necesariamente significa que la respuesta ha sido enviada. Solo significa que hemos llamado a un controlador y asumiremos que ha manejado la respuesta.

De acuerdo, creo que estamos al día. Como dije, puse todo el código allí. Puse el código del servidor allí también, el archivo del servidor. Y creo que estamos listos para pasar a la siguiente parte.

Entonces, ¿qué estabas pensando para la próxima parte? Bueno, lo primero que voy a hacer, es cargar testing esto para ver qué ha sucedido hasta ahora. Así que recuerda, estábamos recibiendo alrededor de 200 y algo mil solicitudes. Mira dónde estamos ahora. Estamos en 176.000, 17.000 en lugar de 25. Así que eso es por segundo, 17.000 solicitudes por segundo. Entonces, ¿qué ha ralentizado tanto esto? Bueno, resulta que a medida que comienzas a procesar estas solicitudes y hacer cosas como crear la URL aquí, esto mismo aquí, es suficiente para ralentizarlo tanto, solo crear la variable URL. O instanciar esa clase, ¿verdad? Entonces, digamos que por eso, cuando estás construyendo estos frameworks, tienes que realizar pruebas de carga continuas para asegurarte de que no hiciste nada loco. Ahora, esto es a propósito, queremos hacer esto. No, no hay nada que podamos hacer al respecto. Queremos crear una interfaz en nuestro framework que sea más accesible que solo el crudo, aquí tienes una cadena para la URL y hacer que la gente la maneje. Así que eso es algo con lo que estamos dispuestos a lidiar. Queremos hacer un seguimiento de esto con el tiempo para asegurarnos de que no estamos degradando el rendimiento mucho más que eso.

De acuerdo, ahora agreguemos otra ruta solo por diversión. Podemos simplemente agregar otra y decir, server.all. Así que esto es genial. Ahora tenemos un servidor funcional. Pondré, haré barra diagonal hola. Agarraré una respuesta de solicitud a continuación y simplemente responderemos con solo mundo esta vez. Así que digamos response.send un mundo. Así que ahora tengo una barra diagonal hola. Debería obtener solo un mundo. Así que veamos. Ahí está. Eso es bastante genial. Quiero decir, no es una cantidad insignificante de código pero tampoco es tanto código ahora construir un enrutador que funcione para un solo controlador. Eso es bastante bueno.

Lo que no funcionará en este momento es lo que queremos poder hacer es tener un registro. Como una de las principales cosas que terminas haciendo con el middleware es tener un registro. Otra cosa que haremos antes de eso es que eso se va a volver más complejo. Entonces, ¿por qué no procesamos el cuerpo? Así que vamos a admitir una solicitud POST. Sí, eso tiene sentido. Ahora eso probablemente sea mejor hacerlo primero. Entonces lo que haremos es algo como esto. Queremos ir a algo como barra diagonal JSON y luego queremos poder obtener nuestra solicitud, respuesta, siguiente. Y luego queremos poder responder simplemente con ese cuerpo de solicitud. Así que queremos poder decir algo como dot body y luego convertirlo en cadena o analizarlo. O en realidad queremos que nuestra respuesta tenga más que solo send. Queremos poder decir response.json y pasar el cuerpo. ¿Verdad? Entonces queremos, es esto aquí, cuando hacemos ese send, solo estamos enviando una cadena en el cuerpo. Pero queremos poder tomar un objeto y enviarlo como respuesta. Así que podrías pensar en ello como, o crear una API REST. No queremos tener que hacer que cada ruta que tengamos, como, tome nuestro objeto y conviértalo en cadena y envíelo de vuelta. Solo queremos y no, luego también tendríamos que establecer los encabezados para application JSON. Así que agreguemos a nuestro objeto de respuesta una función JSON. Entonces iremos a response aquí abajo, o clase. Realmente debería haber puesto todos estos archivos más. Eso es como, locura ahora. Vamos a pasar un objeto desconocido. Así que esperábamos un objeto en este punto. Y luego podemos pasar un estado y encabezados. Mantenme honesto aquí, Will. No estoy mirando ninguna nota, así que.

De acuerdo, luego llamaremos a esto.send. Y necesitamos hacer json.stringify en nuestro objeto. Y luego solo pasamos el estado y los encabezados. Así que ahora hemos creado una función JSON en nuestro objeto de respuesta, donde podemos pasar cualquier objeto. Lo convertiremos en cadena y lo enviaremos. Y parte de los encabezados que queremos agregar es headers.built. Creo que para agregar... Sí, para esto, no creo que tomemos los encabezados. No nos preocupemos por eso por ahora. Solo, sí, solo envía el tipo de contenido. Sí, así que aquí solo haremos content type, application.json. Así que queremos decir, vamos a agregar este encabezado que dice, hey, te estamos enviando JSON. De esa manera, el navegador lo sabe y todo. No es solo una cadena. Es realmente JSON data. Y luego usamos nuestro método send para hacerlo. De esa manera, cada vez que queramos cambiar cómo enviamos data, solo tenemos que hacerlo en un solo lugar, ¿verdad? Sí, pero para esto, queremos cambiar las solicitudes para que la solicitud pueda analizar el cuerpo. Así es, sí. Ahora esperamos en esto, cada vez que llegue esta solicitud, esperamos que obtengamos JSON o algo así. Entonces necesitamos procesar el cuerpo. Puede que no sea JSON. Podría ser solo una cadena, pero necesitamos procesarlo. Así que vamos a decir, déjame buscar esto porque siempre me equivoco. Sí, se convertirá en una función asíncrona y tendremos que usar el decodificador de texto para decodificar el cuerpo y luego analizarlo. Y podemos asumir, simplemente hacer suposiciones por ahora de que siempre enviarás un texto JSON analizable en tu solicitud. Pero aquí es donde, en Express, si alguna vez has usado el analizador de cuerpo, eso es lo que estamos codificando aquí. Y el analizador de cuerpo puede aceptar todo tipo de cuerpos de solicitud, el analizador de cuerpo puede hacer todo tipo de cuerpos de solicitud, pero solo vamos a procesar cuerpos de solicitud JSON. Entonces ahora vamos a decir, déjame sacar esto porque siempre me equivoco, y luego vamos a tener que usar el decodificador de texto para decodificar el valor sin procesar, sí, y luego queremos intentar analizar esto básicamente, y si tiene éxito, bien, si no, realmente no nos importa, está bien, simplemente lo devolveremos como una cadena, básicamente, para ignorar este error porque no es un error real, solo queremos intentarlo y decir, hey, esto podría ser JSON, veamos si lo es o no, si lo es, lo analizaremos, si no, lo dejaremos como está y podría ser undefined dependiendo, y quiero mostrarte qué hace esto también al rendimiento, así que antes de hacer cualquier cosa, Oh, tenemos un error en algún lugar, déjame ver. Sí, ahora tienes que esperar abajo. De acuerdo.

17. Agregando Middleware e Implementando Registro de Acceso

Short description:

Agregamos la capacidad de procesar el cuerpo y enviar un objeto de vuelta. El rendimiento disminuyó en 30,000 solicitudes por segundo, pero aún está en 14,000 solicitudes por segundo. Optimizamos el servidor verificando si la solicitud es una solicitud Git y omitiendo el análisis del cuerpo. La prueba de carga mostró una mejora a 19,000 solicitudes por segundo. Discutimos la importancia de las pruebas de carga y la optimización a lo largo del tiempo. Compartimos el código hasta ahora y el repositorio de GitHub se vinculará más adelante. Explicamos cómo agregar más funcionalidad puede ralentizar el servidor. Discutimos la función de encadenamiento en cascada y cómo se puede implementar. Introdujimos el concepto de middleware y la necesidad de la función next. Explicamos la importancia de manejar una respuesta y el uso de emisores de eventos. Demostramos la implementación de un registro de acceso utilizando los datos de respuesta y solicitud.

En la línea 83, debes esperar a crear la solicitud. Correcto. Oh, y necesito, no, eso ya existe. Necesitas modificar tu interfaz, creo. Supongo que eso lo arregló de alguna manera. Muy bien. De acuerdo, sí, estás bien. Sí. Muy bien. Entonces, ahora vamos a hacer esto en Postman porque queremos enviar realmente algún JavaScript o algún objeto adyacente. Así que abre Postman. Y luego iremos a localhost, wow. Iré a 3000. Barra diagonal JSON. Y vamos a pasar un cuerpo. Un cuerpo. Pasaremos también JSON. Digamos, hola mundo. Muy bien, ahora tenemos que enviar eso. Así que lo enviamos, lo enviamos y luego obtenemos hola mundo de vuelta. Vemos nuestros encabezados, y eso es application.json. Y ahora, en realidad, admitimos procesar el cuerpo y enviar un objeto de vuelta, lo cual es genial. No fue tan difícil agregar eso. Bastante fácil. Muy bien, pero ahora, lo que quiero mostrarte es lo que acaba de suceder. Creo que hemos destruido nuestro rendimiento. Muy bien, ahora nuestro rendimiento es de 14,000 solicitudes por segundo, no tan mal como pensé que sería, en realidad, pero disminuyó en 30,000. Entonces, ahora cuando estamos accediendo a esto, estamos accediendo a nuestro Gitter para la página de inicio. No estamos pasando ningún data y cosas así. Así que nos vimos afectados al agregar, analizar el cuerpo, tenemos el cuerpo de nuestro cuerpo. Y luego, nos vimos afectados al agregar el análisis del cuerpo, en realidad afectamos nuestra solicitud Git. Entonces, lo que podemos hacer es que las solicitudes Git no tienen cuerpos, así que verifiquemos en nuestro, cada vez que estamos creando nuestro objeto de solicitud aquí, verifiquemos y digamos, y solo hagamos esto si la solicitud que el método no es igual a Git. Entonces ahora estamos diciendo, hey, intentemos analizar el cuerpo si no es una solicitud Git, porque si es una solicitud Git, de todos modos no debería haber un cuerpo. Ni siquiera lo vamos a analizar. Ahora, si volvemos y ejecutamos nuestra prueba de carga nuevamente, debería volver a subir. Muy bien, genial. Sí, ahora estamos en 18 o casi 19,000 solicitudes por segundo desde donde estábamos en 14. Así que puedes ver que estos pequeños cambios que hacemos son importantes, así que debes seguir probando la carga y optimizando a lo largo del tiempo para no destruir por completo tu rendimiento. Muy bien, ¿hay algo más que podamos hacer antes de llegar a la?

Sí, tomemos un momento aquí. Primero que nada, vincularemos un repositorio de GitHub con todo el código final una vez que lleguemos allí, pero por ahora, tengo aquí nuestro archivo Hyperbole, el código hasta ahora, y vincularé ese archivo. Sí, cuanto más largo sea el cuerpo, menos solicitudes podrá manejar. Manejará menos solicitudes. Sí, ahora puedes ver cómo comenzamos con un servidor increíblemente rápido, pero a medida que necesitas hacer más cosas, tu servidor se ralentizará. Así que esa es la expectativa que debes establecer, pero puedes ver cómo pequeñas cosas afectarán una cantidad significativa. Después de un tiempo, es como una decadencia exponencial, así que como comienzas a afectarlo ligeramente menos cada vez que agregas cosas nuevas porque ya estás haciendo mucho. Muy bien. De acuerdo, ¿estamos al día? Sí, todo al día. Muy bien. Algo interesante, Matt, que puedes hacer, que vinculé, pero lo vincularé nuevamente. Aquí está mi servidor. Mi server.ts. Y así es como hago el encadenamiento en cascada, que es lo que habíamos configurado. Así que solo tengo server y luego.all y luego.all y.all. Correcto, es como.all. Y.listen al final. Sí, puedes hacerlo de esa manera si te gusta hacerlo de esa manera. Sí, porque alguien hizo una pregunta al respecto, y eso es más o menos... Express lo admite, así que por ahora, ya sabes, lo admitiremos. Correcto. Es prácticamente lo mismo. Solo es una cuestión de preferencia. Muy bien. Ahora, vamos a agregar en nuestro archivo de servidor lo que queremos poder hacer con nuestro middleware. Queremos poder decir, queremos poder agregar algún middleware aquí que se ejecute en cada solicitud. Y lo que eso significa es que ahora tenemos que implementar nuestra función next. Y también necesitamos informar, por lo tanto, con eso, necesitamos informar a nuestro framework cuando una respuesta realmente ha sido respondida porque no se pueden tener dos respuestas para ejecutar solicitudes. Entonces, si estamos pasando por todos nuestros controladores y algo llama a esa respuesta con y responde a una solicitud, no podemos seguir pasando por los controladores y tener otra función intentando llamar a respuesta con y responder a una solicitud porque eso fallará. Una vez que un controlador realmente responde a la solicitud con algún data, tenemos que finalizar esa cadena y terminar con ella. Entonces, realmente tenemos que pensar en cómo vamos a manejar esto ahora. Y llegamos al punto en el que la razón por la que creamos ese objeto de respuesta como una clase ahora, es que vamos a usar emisores de eventos para esto. Pero esto es lo que queremos poder hacer aquí. En nuestro uso, queremos poder decir, queremos poder hacer algo como una duración, quiero obtener esto exactamente como queremos y luego lo implementaremos y lo haremos funcionar. Uno, tienes razón, no necesitas desconocido o fuerza, el cuerpo de cadena es simplemente desconocido en este caso, lo teníamos como cadena y luego agregamos desconocido pero una vez que usas desconocido, desconocido tiene prioridad, tienes razón. Muy bien, lo que queremos poder hacer aquí es algo como esto. Entonces, quiero poder crear una variable llamada inicio y simplemente la igualaré a data ahora. Entonces vamos a crear un registro, puedes acceder a log de acceso. Y luego queremos poder decir, como respuesta en el final. Queremos decir, hey, cuando esta respuesta haya terminado, quiero que llames a esta función y aquí es donde entrará en juego el emisor de eventos. Y luego queremos obtener la duración que es data ahora menos inicio. Y luego queremos mostrar esto en la consola. Podemos hacer, ¿qué podemos hacer aquí? Podemos hacer respuesta que estado. No tenemos esto aún, o ya lo tenemos. Ya lo agregamos. Entonces, y luego queremos, ¿cuál fue el método de solicitud que llegó? Estoy tratando de crear, ya sabes, esto es tu registro de acceso estándar, básicamente. No creo. Y el nombre de la ruta y probablemente la duración. Duración. Y lo haremos en milisegundos. Genial. Y luego aquí es cuando realmente necesitamos llamar a next porque este registro no está respondiendo a las solicitudes.

18. Implementando la Función Next y el Manejo de Eventos

Short description:

Importamos el emisor de eventos y extendemos nuestra clase de respuesta de Hyperbole. Emitimos el evento 'end' cuando la respuesta está lista. Creamos una función envoltorio llamada 'callHandler' para implementar la función next. Escuchamos el evento 'end' y resolvemos la promesa si se llama. Si se llama a la función next, resolvemos la promesa para indicar el paso al siguiente controlador. Llamamos a 'callHandler' en lugar de llamar directamente a las funciones. 'callHandler' devuelve una promesa que evalúa si la respuesta ha finalizado o si se ha llamado a la función next. Creamos un booleano para rastrear si la respuesta ha finalizado.

Está haciendo un procesamiento. Básicamente, obtiene una marca de tiempo. Esto se ejecutará primero y dirá, bien, ¿cuándo comenzó esta solicitud? Y luego, cuando la respuesta esté lista, queremos que se active este evento cuando la respuesta finalice para poder registrar la duración. Esto es algo muy común que terminarías haciendo en Express. Así que queremos que esto funcione. Ahora volvamos a nuestra implementación de Hyperbole y tendremos que hacer algo de trabajo aquí. Sí, primero queremos importar el emisor de eventos. Lo vincularé en el chat. Así que vas a agregar esa importación en la parte superior de tu archivo y eso es lo que vamos a usar para crear o ampliar nuestra clase de respuesta de Hyperbole. Sí, el emisor de eventos es una biblioteca de terceros de Deno. Está alojado en el sitio de Deno. Pero es simplemente... Node tiene un emisor de eventos y sigue la misma interfaz general allí. Sí, probablemente se haya portado desde Node. Sí, ahora que tenemos el emisor de eventos, queremos extender nuestra clase. Por eso estamos usando la clase aquí para la respuesta. Entonces quieres decir 'extends EventEmitter' y luego debemos decirle qué eventos vamos a admitir, así que creemos otro tipo aquí y lo llamaré... Voy a llamarlo 'hyperboleEvents' y solo será 'end'. Necesito cambiar esto a 'hyperboleEvent'. Muy bien, genial. Sí, y debes hacer 'super'. Sí, 'super', me adelanté. Sí, y el emisor de eventos toma, en su constructor, toma un número y ese número equivale a cuántos oyentes puede haber para un solo evento, o tal vez en total, y cero simplemente le dice que agregue, permita tantos como necesitemos. Creo que el valor predeterminado es 200. Ahora, no sabemos cuántas personas pueden querer escuchar estos eventos, así que tenemos que dejar que haga todos ellos. Y ahora lo que queremos hacer es, cada vez que respondemos, necesitamos activar ese evento. Aquí, queremos decir algo como 'this.emit'. Así que ahora tenemos esto aquí porque extendimos el emisor de eventos. Y queremos emitir el final de eso. ¿Correcto? Así que estamos viendo, bien, respondemos. Sí, esto es genial. Así que obtenemos todo, solo con extender el emisor de eventos, vamos a obtener 'on', 'off', 'once' y 'emit' de inmediato aquí sin tener que preocuparnos por el código para eso. ¿Correcto? Así que si venimos aquí, esto debería comenzar a funcionar. Supongo que tengo que reiniciar el servidor de nuevo. Muy bien, sí, ahora estamos bien. Así que ahora nuestra implementación está funcionando, pero esto aún no funcionará porque aún no hemos hecho nada con nuestra función next. Tenemos una función next, pero no estamos haciendo nada. Entonces, en realidad, necesitamos implementar esto. Entonces, cada vez que llamamos a 'processRequest', vamos a crear otra función envoltorio llamada 'callHandler' que implementará la función next para nosotros. Solo una función 'callHandler' y vamos a pasar la solicitud, llamar a la respuesta y el controlador que vamos a usar. Y luego aquí vamos a devolver una promesa. Y será un booleano y lo hacemos por la función next. La función next básicamente va a devolver si queremos ir a la siguiente función que se ha asignado, como en el siguiente controlador de solicitud, o la siguiente función no va a volver, va a volver como falso y decir, eh, no hay más controladores o ya hemos respondido. Sí. Me gusta cómo VSCode es muy prematuro con su... ¿verdad? ¿Verdad? Eso es bastante bueno. Sí. Aquí es donde estamos implementando la función next. Así que estamos llamando al controlador, ¿verdad?, y luego estamos pasando la función next, que se resolverá como verdadera, así que estamos diciendo, eh, llama al método siguiente, por favor, básicamente. Sí, así que esta función 'callHandler' devuelve una promesa y cuando la promesa se evalúa, va a decir si la respuesta ha finalizado o no. Y si ha finalizado, o realmente necesitamos llamar, mover al siguiente controlador o no. Así que si la respuesta ha finalizado, no queremos ir al siguiente controlador, así que resolvemos con falso. Si se llama a la función next, entonces resolvemos con verdadero para indicar, eh, vayamos al siguiente, llamemos al siguiente controlador que tenemos. Sí, por lo que el primero es como si estuvieras manejando eso, si se llama a 'response.send', el segundo es manejar la función siguiente. ¿Correcto? Sí, sí. Entonces, cuando procesamos nuestra solicitud, en lugar de llamar realmente a estos desde aquí, vamos a llamar a 'callHandler'. Así que necesitamos otra cosa aquí también. También queremos saber si ha finalizado o no. Así que creemos otro booleano aquí. Sí, aquí necesitamos saber si la respuesta ha finalizado, no queremos seguir llamando a los controladores pase lo que pase. Esto es solo como un comodín.

19. Handling the Result of Call Handler

Short description:

And we also want to know the result of our call handler if we need to go next or not. So if the event emitter events the end event, we want to say, let's say the request has ended. We've responded. Stop all processing, right? So once listens for the event that you pass in, and it only listens one time. So it's not like you're subscribing and trying to listen multiple times. It's just like a one time listen. All right. All right. So once we, when in our response.send, we're doing this.emitend, then it'll call all these once listeners. Exactly. It listens until it catches the first end event, which we only ever trigger one. But in a real world scenario, you may trigger multiple by accident. The end event could be triggered multiple times, and we don't want to handle it more than once. And what we're going to do here is we're going to, what did I do? What did I screw up? You just haven't, I haven't used the wait method. Yeah, you haven't done the wait yet. We're gonna create a next variable that's false. And then now when we await call handler, that's gonna get populated based on if they called next or not, and that'll let us know if we should keep looping or not. Nice. Yeah, and we probably just call the console log the error here. So we don't really, I mean, if we call these handlers and they fail, we don't really want to, to not continue. I mean, you could continue and something else could handle the requests. So we just want to keep going if we can. Yeah, a lot of times you'll see in an expresser like a global error handler as well. Yeah, yeah, I mean, we don't, we don't have time today to go through all that, but. We could. You can take it further. Take this all the way, it turns out like, it's a lot of work to build these things.

And we also want to know the result of our call handler if we need to go next or not. So if the event emitter events the end event, we want to say, let's say the request has ended. We've responded. Stop all processing, right? So once listens for the event that you pass in, and it only listens one time. So it's not like you're subscribing and trying to listen multiple times. It's just like a one time listen.

All right. All right. So once we, when in our response.send, we're doing this.emitend, then it'll call all these once listeners. Exactly. It listens until it catches the first end event, which we only ever trigger one. But in a real world scenario, you may trigger multiple by accident. The end event could be triggered multiple times, and we don't want to handle it more than once. And what we're going to do here is we're going to, what did I do? What did I screw up? You just haven't, I haven't used the wait method. Yeah, you haven't done the wait yet. We're gonna create a next variable that's false. And then now when we await call handler, that's gonna get populated based on if they called next or not, and that'll let us know if we should keep looping or not. Nice. Yeah, and we probably just call the console log the error here. So we don't really, I mean, if we call these handlers and they fail, we don't really want to, to not continue. I mean, you could continue and something else could handle the requests. So we just want to keep going if we can. Yeah, a lot of times you'll see in an expresser like a global error handler as well. Yeah, yeah, I mean, we don't, we don't have time today to go through all that, but. We could. You can take it further. Take this all the way, it turns out like, it's a lot of work to build these things.

20. Implementando el Framework Oak y Vinculando el Repositorio de GitHub

Short description:

Vemos los registros de la consola al acceder al servidor. La prueba de carga muestra una disminución en las solicitudes por segundo debido a los registros de la consola. Discutimos el framework Oak para Deno, que está listo para producción. Vinculamos el repositorio de GitHub y explicamos el uso de guiones bajos en el linter de Deno.

Muy bien, ahora necesito. Sí, esto es bueno. ¿Sí, lo es? ¿Verdad? Sí. Ahora deberíamos comenzar a ver nuestros registros de consola cada vez que accedemos al servidor. Vamos a acceder a nuestro 'hello'. Oh. Así que vincularé nuestro... Nos estamos quedando colgados. Vincularé el código hasta este punto que tengo. No estamos terminando. Me perdí algo en algún lugar. Oh, llamé a next aquí. Sí, todo parece correcto. Ahora ve a tu código. El código, pero. Eso parece correcto. ¿Llamé a callHandler, me perdí algo en el? ¿Y en la respuesta, hiciste el emit ahí? Creo que sí. Sí, quiero decir, sí, lo hice. ¿Dónde está? Sí, esto. Ese emit ahí. De acuerdo. Así que eso debería estar correcto, ¿verdad? Sí, y luego callHandler. Sí, callHandler. Devolví una nueva promesa. Resolver get. No llamaste al async, la segunda función iterable asíncrona. No hiciste una función ejecutada inmediatamente allí. Eso es un problema, ¿verdad? La URL ya contiene el nombre de la ruta. Matt simplemente hizo una variable de nombre de ruta fácil allí para facilitarte las cosas. Sí, lo subí un poco para simplemente hacer request.pathname. No tienes que agregar eso, obviamente. Podrías simplemente hacer request.url.pathname. Digo, agrega eso. Sí, entonces habrías recibido una respuesta en el navegador ya, pero lo que hace ese registro es que en realidad registra en la consola del servidor. Por lo tanto, registrará la información de la solicitud y la información de la respuesta. Sí, ahora cuando estoy aquí, ves que estoy obteniendo. Es un 200. Fue nuestra respuesta. Fue un método get, y fue en la ruta raíz, y son dos milisegundos. Ahora, si voy a algo como slash hello, y volvemos, ahora podemos ver que respondimos con el 200, el get slash hello. Cero milisegundos, súper rápido, y luego podemos llamar a nuestro post. Ahora vemos que es un post en slash JSON, cero milisegundos. ¡Bam! Y ahora cada vez que llamamos a nuestro. Esto también es interesante. Ahora vamos a hacer nuestra prueba de carga. Y esto te dará una idea de por qué debes eliminar tus registros de consola cuando vayas a producción. Recuerdo que estábamos obteniendo... Bueno, creo que era, estábamos obteniendo 18,000 solicitudes por segundo, sí, casi 19. Y ahora estamos obteniendo 15,000 solicitudes por segundo. Eso es simplemente porque estamos registrando en la consola. Eso es lo que hace el registro de la consola. Es una función bastante costosa porque tiene que escribir en la salida estándar. Sí, y hace algunas operaciones matemáticas de fecha. Sí, y ahora si venimos aquí, mira cuántas respuestas tenemos. Sí, también hay algunas operaciones matemáticas de fecha. Eso es genial. Respondió a todas esas. Muy bien, ¿hay alguna pregunta? Eso es todo el código que teníamos para hoy. También podemos mostrar oak y sus cosas. ¿Qué es eso? También podemos mostrar oak y cosas. Oh sí, podemos hacer oak rápidamente. Pero quiero decir, para un masterclass que vale la pena codificar, ahora tenemos un framework bastante útil para construir algo. Ahora falta mucho de lo que querrías en un framework completo, por eso vamos a mostrar oak. Oak es un framework web muy bueno para Deno, y también es compatible con Hyper, siempre que se ejecute en modo inestable. Así que creemos un pequeño Hola mundo con oak. Sí, la información que usas es problemática, aunque cuando haces cosas como esperar a next res dot send, sí, puedes, no llamará al segundo controlador. Entonces, no hemos llevado esto tan lejos, por eso estamos demostrando oak en este momento. Solo queríamos darte un ejemplo de cómo podrías comenzar a escribir un servidor web así. Pero en la práctica, no necesariamente llevaría esto y lo implementaría en producción. Oak es un- Es un framework de servidor listo para producción para Dino. Entonces, si vas a usar Dino, pensé que sería genial para un masterclass que puedas ver cómo funciona internamente de lo que estás haciendo con estos frameworks, porque es bastante interesante. Quiero decir, es bueno saber qué está pasando realmente cuando usas estos frameworks. Así que ahora voy a, creo que es el momento de vincular el repositorio de GitHub con todo nuestro material aquí. Oh, por supuesto, un poco diferente. Entonces no tiene request response, tiene este objeto de contexto. Y luego el objeto de contexto tiene en realidad la respuesta que es el cuerpo que puedes establecer, lo estableces. Responderá con ese cuerpo. Sí, cuando prefieres algo con el guion bajo, es una forma de decir, eh, no lo voy a usar. En realidad es un Dino. Por lo tanto, el error que obtienes se basa en el linter de Dino. Dino tiene un linter incorporado. Y te permite hacer el guion bajo y luego no obtendrás el error de linter. Sí, si no pongo el guion bajo, obtengo un error de linter que dice, eh, declaraste next, pero nunca lo usaste. Y hay patrones comunes en otros lenguajes donde el guion bajo significa, voy a obtener esto pero no lo voy a usar. Específicamente en Go, eso es otra cosa que puedo mencionar. Como en Dino, está modelado según Go. Entonces, si ejecutamos dino-help, verás que hay muchas cosas aquí que también están en Go. Hay un formateador que ya está para ti, hay un linter. Muchas de las cosas que ves aquí son en realidad de Go. Y si vas a ver la biblioteca estándar, como muchas de las implementaciones tendrán las referencias a Go en ellas.

QnA

Usando el Framework Oak y Preguntas y Respuestas

Short description:

Ejecutamos Oak, un framework construido sobre Hyper, y observamos una respuesta ligeramente más lenta en comparación con nuestro framework debido a su funcionalidad adicional. Oak es recomendado para construir sitios web y APIs con Deno, ya que es un framework bien soportado y ampliamente utilizado mantenido por los desarrolladores de Dino. Construimos un framework funcional en este masterclass, pero hay más cosas que se pueden agregar para hacerlo listo para producción. Discutimos el flujo de una solicitud desde el navegador hasta la respuesta, y el ejemplo de decodificación de JSON del cuerpo de la solicitud. Gracias por asistir a la sesión y siéntete libre de hacer cualquier pregunta.

Como, hey, estamos portando esto desde Go, lo cual es genial. Muy bien, ahora estoy en Oak. Parece que, ¿lo escribí bien? Dno punto land slash x slash oak, siete punto cinco punto cero. Permíteme intentar ejecutar esto. La importación falló, así que obtuve algo, ¿qué escribí mal aquí, no lo veo. Dno land slash x, creo que es v, v siete punto cinco punto o. Oh no, eso es todo. Eso es lo que está sucediendo. Muy bien, ahora estamos ejecutando Oak y puedes ver que tiene una interfaz diferente a la que estamos acostumbrados. Pero te darás cuenta de que está utilizando Hyper en el fondo. Entonces, si lo probamos con una prueba de carga. Y será similar a lo que teníamos antes de hacer el registro en la consola. El registro en la consola realmente te confunde, pero sí, estamos obteniendo 13,000. Así que es un poco más lento pero este framework está haciendo mucho más que nuestro framework, así que es comprensible. Ahora diría, así que ve a ver Oak si vas a construir un sitio web o una API o lo que sea con Dino. Definitivamente recomendaría usar Oak. Es un framework realmente genial y también es mantenido por algunos de los desarrolladores de Dino, por lo que tiene un gran soporte y es ampliamente utilizado, así que échale un vistazo. Muy bien, eso fue divertido. Construimos todo un framework web en un masterclass. Espero que hayas aprendido algo o simplemente te hayas divertido jugando. Creo que eso es lo que fue esto. No creo que esperemos que alguien salga de aquí y cree un framework web pero pensamos que era una buena manera de mostrar cómo Dino usa Hyper, cómo es mucho más rápido y luego cómo podrías construir algo a su alrededor y esperamos que te dé un poco más de respeto por estos desarrolladores de frameworks y lo que implica construirlos porque hay mucho en ello. Y construimos un framework relativamente funcional pero hay mucho más que querrías agregar a esto para hacerlo listo para producción. Muy bien, eso es todo.

¿Tenemos alguna pregunta antes de terminar? Estoy vinculando el repositorio, el repositorio correcto. Vinculé uno diferente allí. Oh. Estoy vinculando el repositorio correcto en el chat ahora mismo para que puedas tomarlo y usarlo más tarde. Sí. Muy bien. Bueno, gracias por venir a esta sesión. De nuevo. Tenemos algunas preguntas que llegan así que podemos quedarnos y responder algunas preguntas. Responderemos preguntas. Claro. Si lo que creamos es un framework, no hay frameworks de Deno que hagan esta estructura básica por nosotros. ¿Correcto? No, no hay un framework incorporado de Deno para esto. Sin embargo, OAK es un estándar de facto que la gente usa para construir aplicaciones web con Deno. Así que implementa una interfaz similar, ligeramente diferente a lo que hicimos hoy pero también tiene mucha más funcionalidad completa, por lo que es un framework de servidor listo para producción. Solo creamos, ya sabes, te dimos una idea de cómo podría ser escrito, pero en producción te sugiero usar algo como OAK. Como este que estamos viendo aquí es OAK. Entonces la segunda pregunta, ¿podríamos revisar el flujo? ¿Qué sucede cuando el navegador llega al servidor y solicita la solicitud hasta la respuesta? Supongo. Sí, muy bien. Lo explicaré. Si estamos en horas, vamos a ir a hyperlink. Lo primero que sucede, si vamos a la función listen y trabajamos desde allí. Entonces llamamos a listen, eso va a esperar la conexión. Esperar la conexión. Aquí es donde comienza a escuchar en el puerto TCP, ¿verdad? Así que está escuchando en el puerto TCP que sea, que en este caso es 3000. Entonces el navegador, presionas enter en localhost 3000 y luego se inicia una conexión TCP. Ahí es donde se recoge esto. Esto dice, muy bien, hey, tengo una conexión. Este bucle espera las diferentes conexiones. Una vez que obtiene la conexión, la entrega a la función handleHttp. Y handleHttp es donde invocamos a Hyper, donde decimos, hey, queremos usar la conexión TCP, y encima queremos usar HTTP. Así que pasamos la conexión y luego eso devuelve un evento de solicitud, creo, que tiene respondWith y request. Instanciamos nuestra solicitud y respuesta. Estas son nuestras, las que creamos, la solicitud de hyperbole y la respuesta de hyperbole, las instanciamos, que es donde procesamos un poco los datos. Como procesamos el cuerpo, procesamos la URL, lo hacemos un poco más fácil de trabajar. Luego pasamos eso a process request, que es donde comenzamos a averiguar qué controlador debe procesar esta solicitud en particular. Queremos escuchar cuando, o cuando termina, como cuando hemos respondido a la solicitud, queremos detener todo el procesamiento porque solo podemos responder a una solicitud una vez. No queremos que haya un montón de controladores disparándose e intentando responder. Disparamos los controladores uno a la vez de forma sincrónica, por eso tenemos el await aquí. Bajamos y buscamos una coincidencia. Buscamos algo que coincida con la ruta. Si vamos a nuestro servidor, vemos que tenemos estas rutas. Tenemos slash JSON, slash para la página de inicio, y slash hello. Esas son las únicas rutas que estamos escuchando. Cuando volvemos aquí, si la ruta coincide, entonces queremos llamar al controlador que pasamos para eso ahí. Y luego, si ninguna coincide, eso significa que no hemos manejado la solicitud, necesitamos enviar un 404 porque eso significa que no conocemos esto. No se creó ningún controlador para eso. Así que queremos enviar un 404. Y eso es prácticamente todo. Entonces wait for connection se ejecuta constantemente. Esto no se ejecuta solo una vez. Está aquí esperando tantas conexiones como- hay muchas conexiones TCP desde los navegadores. Por eso mantiene el servidor abierto y en funcionamiento, está esperando conexiones TCP. Cuando obtiene una conexión TCP, decimos, hey, sabemos que solo nos importa HTTP. Así que se lo pasamos a serve HTTP. Y ahí es donde entra Hyper y procesa todas las cabeceras y el cuerpo y todo eso por nosotros. Y luego lo llevamos desde ahí. La conexión se cerrará cuando hagas respond with. Así que terminará cerrando la conexión porque reconoce que todos los datos se han enviado y ha terminado. Vamos a repasar el ejemplo de JSON una última vez. Repasemos la parte del JSON como crear el JSON. Oh, en la solicitud. Sí, cuando envías una solicitud JSON, vamos y miramos el cuerpo y decimos, usamos un decodificador de texto incorporado que está en Deno y decodificamos. Sí, y simplemente decodificamos el valor, el valor sin procesar y luego lo analizamos como JSON. Esto no es lo que harías si fueras a escribir, como un framework de servidor completo, no necesariamente harías esto. Podrías decodificar según el tipo de contenido que se pasa en la solicitud pero simplemente tomamos un atajo para esto.

Decodificación de Bytes sin Procesar

Short description:

Es un flujo legible de una matriz UN8, lo que significa que es una matriz de bytes. Creamos un decodificador y lo ejecutamos en el valor del lector para obtener una cadena. Luego podemos usar esa cadena para analizar los datos.

Sí, lo que sucede es que Hyper no hace nada con el cuerpo. Si miras el tipo aquí, es un flujo legible de una matriz UN8 lo que significa que es simplemente una matriz de bytes. Es como bytes sin procesar. Entonces tienes que decir, bien, tengo bytes. ¿Qué son? ¿Qué hacemos con ellos? Bueno, asumimos que va a ser texto que viene como una cadena JSON o un formulario de una solicitud que necesitaríamos decodificar de manera diferente aquí. Así que creamos este decodificador y luego lo ejecutamos en el valor que obtenemos del lector. Esto nos da un lector que lee los bytes sin procesar en una variable. Ahora esto es un flujo, un flujo sin procesar de bytes y luego pasamos eso al decodificador y nos devuelve una cadena y podemos usar eso para intentar analizarlo.

Deno as a Replacement for Node

Short description:

La comunidad de Node no ve a Dino como un reemplazo de Node. Dino está en una etapa temprana de su ciclo de vida y carece de las extensas bibliotecas y utilidades de terceros que tiene Node. Sin embargo, Dino ofrece beneficios como ser un único archivo binario, compilación cruzada y la capacidad de convertir JavaScript en un ejecutable. Proporciona seguridad de forma predeterminada al restringir el acceso a la red y al sistema de archivos.

Sí, mencionaré algo controvertido. Bueno, supongo que no es una pregunta, es más una afirmación y luego una pregunta, pero dice que la comunidad de Node no ve a Dino como un reemplazo de Node, ¿cuál es tu opinión? Ten en cuenta que esta es una opinión, no está respaldada por nadie. No creo que en este momento haya forma de que Dino sea un reemplazo de Node. Aún está en una etapa temprana de su ciclo de vida. La comunidad de Node es muy madura y robusta. Hay muchas bibliotecas y utilidades de terceros y cosas que están en Node que simplemente no tienes en Dino en este momento. Entonces, lo que está haciendo el equipo de Dino es crear polifills o cosas para que algunos paquetes de Node se ejecuten en Dino, lo cual será útil para acelerar lo que puedes hacer en Dino. Pero, en este momento, definitivamente no lo llamaría un reemplazo, pero para mí, es una plataforma mucho mejor para construir en el futuro. En primer lugar, Dino es un único archivo binario, a diferencia de Node que es una instalación grande que debes instalar con un montón de cosas, es una instalación grande. Y necesitas un administrador de paquetes dedicado y todo eso. Sí, Dino es literalmente solo un archivo binario. Eso es todo. Puedes tomar Dino y es un archivo, puedes mover Dino a cualquier lugar que desees y simplemente ejecutarlo. No tengo que instalar nada. Y se compila cruzadamente, todo está escrito en Rust. Otro beneficio es que puedes hacer Dino compile, y eso tomará tu JavaScript y lo convertirá en un ejecutable. Entonces, mi archivo JavaScript que creo, podemos hacer eso con el servidor que acabamos de crear, y podemos tomar eso. Obtendremos un archivo de ese único ejecutable. Y podemos ejecutarlo en cualquier plataforma. Ni siquiera necesito tener Dino en esa plataforma. Solo necesito mi ejecutable. Entonces, hay escenarios en los que Dino realmente ofrece cosas que Node no tiene. Además, si te importa la seguridad. Es como seguridad de forma predeterminada. Si no ponemos esa red permitida, no funciona. Nuestro código no tendrá acceso a la red. Y por defecto, nuestro código tampoco tiene acceso al sistema de archivos. Entonces, no podemos leer archivos. Entonces, obtienes cierta seguridad de esa manera también. Hay... Sí, creo que eso es una de las cosas que me encantan de Dino, porque realmente puedes tener problemas con Node.

El Futuro de Deno y el Uso de Rust

Short description:

Ahora, muchas personas ejecutan Node dentro de un contenedor o en producción sin acceso al sistema de archivos. Sin embargo, el acceso ilimitado al sistema de archivos de Node puede ser peligroso. Deno aún no es un reemplazo para Node, pero estoy emocionado por su futuro y la reimaginación de las bibliotecas. El uso de Rust en Deno garantiza un código más rápido y seguro, lo que lo hace ideal para aplicaciones sensibles a la seguridad. Rust se utiliza ampliamente y se está adoptando en diversos proyectos. Soy un firme creyente en Rust y su potencial. No hay más preguntas por el momento.

Ahora, muchas personas ejecutan Node dentro de un contenedor o algo similar en producción y es posible que no tengan acceso al sistema de archivos. Pero realmente puedes tener problemas si no tienes cuidado en Node, ya que tiene acceso ilimitado a tu sistema de archivos. Ha habido casos en el pasado en los que alguien ha escrito un paquete malicioso y ha tomado el control de tu computadora. En mi opinión, Deno no es un reemplazo en este momento. Sin embargo, estoy realmente emocionado por Deno y lo que aporta tanto ahora como en el futuro. Estoy emocionado por el día en que las personas creen polifills uno a uno para muchas bibliotecas populares de Node en este momento. Estoy emocionado por el día en que las personas hayan tomado la esencia de Node y la hayan repensado, reimaginado de una manera diferente que solucione algunos de los puntos problemáticos de Node. Estoy emocionado por el día en que las personas hayan portado bibliotecas de una manera en la que se hayan reimaginado. Así que ahora te deshaces de parte de la deuda técnica y las decisiones arquitectónicas que simplemente no funcionaron, pero tienes que admitir todo. Estoy realmente emocionado por ese día, cuando obtengamos nuevas bibliotecas para Deno que sean más esenciales de Deno y menos esenciales de Node. Otra cosa que me gusta de Deno, en cuanto al futuro, es que está escrito en Rust. Y lo que estamos empezando a ver con Rust es que se está utilizando para reescribir mucho código, mucho código de bajo nivel que hay. Debido a que es seguro en cuanto a la memoria, te obliga a escribir código correcto y debido a eso, al final obtienes un código más rápido, como C en Rust. ¿Van a ser técnicamente más rápidos que C si escribes código C perfecto? Tal vez C sea ligeramente más rápido, pero nadie está escribiendo código C perfecto. Por lo general, el código que reescribes en Rust es en realidad más rápido y más seguro. Soy un gran creyente en Rust y creo que veremos mucho código muy sensible a la seguridad que se reescribirá en Rust. Y ahora estamos viendo que Rust se utiliza en el kernel de Linux y en Android. Está en todas partes. Así que soy un gran fan de Rust y esa es una de las razones por las que me incliné hacia Deno, porque está escrito en Rust. ¿Tenemos algo más, Will? No veo nada.

Usando Deno para Bibliotecas y Producción

Short description:

Actualmente no hay una buena solución para escribir bibliotecas principalmente para Deno y también compilarlas para Node. Sin embargo, existen polyfills disponibles para Node que pueden hacer que ciertas funcionalidades funcionen. Para aplicaciones web con Node, Express y React, puedes usar el framework alfjs, que es un framework de React para Deno. Se recomienda encarecidamente el uso de TypeScript con Deno debido a sus numerosos beneficios en términos de productividad y escalabilidad. Sin embargo, aún puedes usar JavaScript con Deno si lo prefieres. En cuanto al uso de Deno en producción, depende de los requisitos específicos de tu aplicación. Deno está listo para servidores web básicos, pero para APIs más complejas y un uso extensivo de la API de Deno, es posible que necesites considerar polyfills o seguir utilizando Node por ahora. La comunidad de Deno ofrece una gran oportunidad para los primeros adoptantes de contribuir y construir proyectos que sean más idiomáticos para Deno. El objetivo de Deno es ser lo más compatible posible con la web, utilizando APIs del navegador siempre que sea posible. Además, hay un podcast llamado Decode que cubre diversos temas, incluyendo TypeScript y sistemas de gestión de contenido sin cabeza. WordPress puede funcionar como un CMS sin cabeza, y plugins como WP GraphQL facilitan el uso de WordPress para los datos mientras se aloja el front-end en otro lugar.

No veo nada.

Sí, hubo una pregunta, ¿sabes si hay una buena solución para escribir bibliotecas principalmente para Deno y también compilarlas para Node? No tengo conocimiento de ninguna. No sé si hay una biblioteca, pero hay algo ahí fuera donde están escribiendo los polyfills para Node. Por ejemplo, si intentas leer desde el sistema de archivos utilizando Node, si importas fs y lees desde el sistema de archivos, hay cosas que harán que funcione. Pero creo que habrá un poco de trabajo que tendrás que hacer específicamente solo para la importación. Deno utiliza los módulos esm, por lo que importas utilizando URLs y el nombre completo como .ts, y eso no se hace en Node. Así que habrá algunas cosas allí que probablemente tengas que hacer desde esa perspectiva, pero están tratando de facilitarlo con el tiempo.

Alguien dice: Estoy acostumbrado a crear aplicaciones web con Node, Express y React, como proyectos de plantilla. ¿Sabes si hay algo así con Deno? Sí, está alfjs. Es un framework similar a Next.js para Deno. Es un framework de React para Deno. Tiene enrutamiento basado en el sistema de archivos y muchas otras cosas, como SSR, SSG, todas las cosas que puedes estar acostumbrado en Next y React. Todo en un solo framework. Así que échale un vistazo.

¿Necesitas usar TypeScript con Deno, por qué no JavaScript? JavaScript es un lenguaje intermedio que no debe ser modificado por manos humanas. Así que no usaría JavaScript. Quiero decir, no usaría JavaScript directamente. TypeScript te ahorra mucho. Sé que si no estás acostumbrado a TypeScript, puede haber una ligera inercia que debes superar para sentirte realmente cómodo con él. Pero una vez que lo hagas, los beneficios son enormes. Simplemente no tiene sentido. Es como C versus Rust, aunque no están tratando de ser técnicamente más rápidos que C si escribes código C perfecto. Tal vez C sea ligeramente más rápido, pero nadie está escribiendo código C perfecto. Por lo general, el código que reescribes en Rust es en realidad más rápido y más seguro. Soy un gran creyente en Rust y creo que veremos mucho código muy sensible a la seguridad que se reescribirá en Rust. Dicho esto, puedes usar JavaScript. Puedes simplemente escribir el archivo JavaScript y ejecutarlo con Deno y funcionará bien. Sí, puedo crear un nuevo archivo aquí, como test.js, y ejecutarlo y listo. Creo que deberían agregar una advertencia. Sí, quiero decir, si cambias el server.ts a server.js, puedes ejecutar los servidores. Es cierto. Archivo JS. Porque no tienes ninguna tipificación explícita allí. Entonces, sí, ahora es un archivo JS. Esto ya se estaba ejecutando. Así que puedo ejecutar server.js y estamos en marcha. Sí, es una opción u otra, pero recomendaría que uses TypeScript. Sí, cualquier otra cosa? Algunas personas están escribiendo, así que podría haber algo. ¿Usarás un servidor Deno en producción ahora? En realidad, creo que ahora es probablemente el momento de hacerlo si estás creando una nueva aplicación. Puedes tomar una decisión sobre lo que implica la aplicación, qué necesito hacer. Y puedes investigar un poco y determinar si Deno es adecuado para ti como servidor de producción. Si estás creando un servidor web básico y no tienes que hacer muchas API y usar muchas de las API de Deno, está totalmente listo en este momento. Realmente depende de lo que necesites hacer. Como dijimos, están trabajando en polyfills para muchas de las bibliotecas de Node para que sea más agradable, pero dependiendo de lo que necesites hacer, es posible que Deno ya lo admita y, si no lo hace, es posible que uses Node por ahora. Y también diré esto, hay una gran oportunidad para todos en este momento de unirse a la comunidad de Deno desde muy temprano, construir algunas de las cosas que faltan. E imagino que las personas que se unieron a la comunidad de Node temprano, eso es lo que estamos haciendo ahora con Deno. Como que hay muchas oportunidades para unirse a la comunidad, contribuir, construir proyectos que sean más idiomáticos para Deno. Sabes, importar algo de Node no es necesariamente la respuesta correcta porque Deno hace las cosas de manera diferente. Tiene pesos de nivel superior y no se basa en devoluciones de llamada como Node. Se basa mucho en cosas asíncronas, utilizando un peso único, y tienes iterables y cosas así. Así que escribimos este framework para darte la esencia de Express pero con Deno. Quiero decir, podrías reimaginar un framework utilizando más cosas a nivel de Deno. Eso es lo que hace Oak. Correcto. Y creo que eso es lo que deberías hacer. Queremos ver que eso aparezca en la comunidad porque quieres ver que las personas aprovechen todas las cosas que tiene Deno. La mayoría de las cosas que están en Deno también están en el navegador, lo cual creo que es realmente genial. Intenta utilizar APIs del navegador siempre que sea posible para que tu código pueda funcionar tanto en Deno como en el navegador. Y también tenemos un podcast llamado Decode donde uno de nuestros episodios se centra exclusivamente en TypeScript. Hemos estado minimizándolo hasta ahora, pero tanto Matt como yo somos grandes fanáticos de TypeScript y lo hemos sido durante mucho, mucho tiempo antes de que fuera público, y definitivamente es mejor para la escalabilidad. Sí, he sido parte de varios proyectos de JavaScript que terminaron con cientos de miles de líneas de código de JavaScript, y aunque admito que las herramientas para JavaScript hoy en día son mucho mejores que hace seis o siete años y están mejorando todo el tiempo, las herramientas para TypeScript eran mucho mejores hace cinco años que para JavaScript, y todavía son mejores hoy en día, y las cosas que obtienes, como poder refactorizar de manera segura los nombres de las variables y agregar funciones y cambiar las firmas de las funciones y comprender cómo afectará a tu código, eso simplemente conduce a una mejor escalabilidad en un proyecto de TypeScript. Seguro. Sí, compartiré el episodio, así que lo compartiré en Apple, Spotify, Google. Spotify. Google. Esos son probablemente los más importantes aquí. Así que aquí está, aquí está el episodio de TypeScript en Apple. Aquí es donde puedes encontrarlo en Spotify. Y aquí es donde puedes encontrarlo en Google, si lo usas. Sí, y nuestro podcast Decode habla de muchas cosas como esta. También hablamos de sistemas de gestión de contenido sin cabeza, otras características interesantes del front-end y cosas que vendrán en el futuro. También entrevistamos a personas del campo sobre su experiencia, así que hemos tenido algunos invitados en el pasado. Gran parte de ese podcast se centra en WordPress como un CMS sin cabeza, que es en lo que estamos trabajando para mejorarlo como parte de WP Engine. Bien, cuando WordPress se convierte en un CMS sin cabeza, es solo una API para tu front-end, por lo que gran parte de nuestro contenido se trata de esas aplicaciones de front-end. Sí, muchas personas no se dan cuenta de esto, sin profundizar demasiado, pero muchas personas no se dan cuenta de que WordPress, sabes, no he estado usando WordPress durante mucho tiempo. Creo que hace 10 años usé WordPress y luego hice una pausa y volví en los últimos años. Y WordPress funciona bastante bien como un CMS sin cabeza. Y lo que eso significa es que apagas la parte frontal de WordPress y alojas tu front-end en otro lugar. Y luego usas WordPress solo para los datos. Muchas personas no se dan cuenta de que eso es posible. Pero hay algunos plugins para WordPress que lo hacen mejor hoy en día que nunca. El más importante es WP GraphQL, que es una API de GraphQL construida sobre WordPress, lo que facilita mucho las consultas y la obtención de contenido y cosas por el estilo. Sí, permite que tus usuarios sigan iniciando sesión en WordPress, a lo que probablemente estén acostumbrados, y creen todo su contenido, pero luego no tienes que usar WordPress y construir el sitio web.

Elección de CMS y lenguajes de plantillas

Short description:

Puedes usar lo que quieras. Deno, Node, React, Vue, lo que sea. Dependiendo del propósito del sitio, WordPress puede ser preferible a Markdown. CMS alternativos como Contentful, Strappy y Firebase ofrecen diferentes opciones para los backends. Los lenguajes de plantillas como Mustache y EJS están disponibles para Deno. Puedes encontrar módulos y plugins similares al ecosistema de Node en deno.land/X. Gracias a todos por asistir. Visita developers.wpengine.com para obtener más información y únete a nuestra comunidad de Discord para recibir soporte y participar en discusiones.

Puedes usar lo que quieras. Deno, Node, React, Vue, lo que sea. Sí, sí, por lo general, he asumido en el pasado que, bueno, simplemente tendré algunos archivos Markdown alojados en GitHub o en otro lugar y las personas pueden editar Markdown y eso será suficiente para ellos. Y luego, me di cuenta de que ciertos editores, comercializadores y diferentes personas, no están muy interesados en editar archivos Markdown o incluso en editar Markdown en un editor más agradable. Prefieren la experiencia que obtienen en WordPress y es una experiencia de publicación ligeramente mejor. Por eso, siempre es una consideración para mí, dependiendo de para quién estoy construyendo un sitio, si voy a usar WordPress o si simplemente voy a construir un sitio personal, tal vez diría que estoy bien con Markdown, está bien. Correcto, de acuerdo.

Sí, así que hay alternativas. También hay otros CMS. Además de WordPress, hay opciones como Contentful y Strappy si realmente quieres tener un CMS enfocado en los desarrolladores. También está Firebase si estás construyendo una aplicación y quieres crear fácilmente una API. Y sí, hay muchos backends diferentes. Incluso si estás utilizando WordPress como un CMS sin cabeza, eso no significa que necesites usar Node en el frontend o Deno o cualquier otra cosa. Puedes tener un servidor Python en el frontend, puedes tener un servidor C Sharp, puedes tener Java, puedes hacer lo que quieras, lo que sea conveniente. Entonces, si tienes un CMS sin cabeza, donde solo tienes tu API para tu CMS, y luego tu frontend es lo que quieras, lo que te resulte cómodo y lo que tenga más sentido para lo que estás haciendo en el frontend. Sí, de acuerdo.

¿Existen lenguajes de plantillas como pug, mustache, Hamel o EJS para Deno? Oh, esa es una buena pregunta. Estoy seguro de que los hay, si vas a, si vas a deno.land/X, ups, no hasta Oak, pero si vas a /X, aquí es donde se publican todos los módulos. Así que, veamos. Sé que hay, hay varios lenguajes de plantillas diferentes. Hay mustache aquí. Motor de plantillas EJS para Deno, D-E-J-S. Así que sí, están aquí. Puedes venir aquí y buscar si quieres encontrar algo. Sí, notarás que hay una buena cantidad de complementos o módulos que estás acostumbrado a ver en Node que también existen para Deno. Sí, cosas como Fuse son geniales porque ya solo usaban estándares web. Así que funcionará en Deno por defecto porque se ejecuta en el navegador. Si se ejecuta en el navegador, se ejecutará en Deno. Así que, quiero decir, suponiendo que no estés utilizando el DOM.

Gracias a todos por asistir. Fue divertido. Logramos pasar sin muchos tropiezos. Siempre es genial. Estaba preocupado por eso en este caso. Sí, y ambos, todo lo de Deno se ejecuta en V8 y también todo en Node. Bueno, no necesariamente en el navegador, dependiendo del navegador que estés utilizando, pero sí. Genial. De acuerdo. Bueno, gracias a todos por asistir. Aprecio mucho que hayan pasado tiempo con nosotros, y si tienen alguna pregunta o algo, vayan a developers.wpengine.com, y tenemos un servidor de Discord al que pueden unirse, y pueden hacer preguntas y chatear con nosotros en la comunidad y pasar el rato, y estaremos allí. De acuerdo, salgan y usen Deno y feliz codificación.

Watch more workshops on topic

Node.js Masterclass
Node Congress 2023Node Congress 2023
109 min
Node.js Masterclass
Top Content
Workshop
Matteo Collina
Matteo Collina
Have you ever struggled with designing and structuring your Node.js applications? Building applications that are well organised, testable and extendable is not always easy. It can often turn out to be a lot more complicated than you expect it to be. In this live event Matteo will show you how he builds Node.js applications from scratch. You’ll learn how he approaches application design, and the philosophies that he applies to create modular, maintainable and effective applications.

Level: intermediate
Build and Deploy a Backend With Fastify & Platformatic
JSNation 2023JSNation 2023
104 min
Build and Deploy a Backend With Fastify & Platformatic
WorkshopFree
Matteo Collina
Matteo Collina
Platformatic allows you to rapidly develop GraphQL and REST APIs with minimal effort. The best part is that it also allows you to unleash the full potential of Node.js and Fastify whenever you need to. You can fully customise a Platformatic application by writing your own additional features and plugins. In the workshop, we’ll cover both our Open Source modules and our Cloud offering:- Platformatic OSS (open-source software) — Tools and libraries for rapidly building robust applications with Node.js (https://oss.platformatic.dev/).- Platformatic Cloud (currently in beta) — Our hosting platform that includes features such as preview apps, built-in metrics and integration with your Git flow (https://platformatic.dev/). 
In this workshop you'll learn how to develop APIs with Fastify and deploy them to the Platformatic Cloud.
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
GraphQL - From Zero to Hero in 3 hours
React Summit 2022React Summit 2022
164 min
GraphQL - From Zero to Hero in 3 hours
Workshop
Pawel Sawicki
Pawel Sawicki
How to build a fullstack GraphQL application (Postgres + NestJs + React) in the shortest time possible.
All beginnings are hard. Even harder than choosing the technology is often developing a suitable architecture. Especially when it comes to GraphQL.
In this workshop, you will get a variety of best practices that you would normally have to work through over a number of projects - all in just three hours.
If you've always wanted to participate in a hackathon to get something up and running in the shortest amount of time - then take an active part in this workshop, and participate in the thought processes of the trainer.
Mastering Node.js Test Runner
TestJS Summit 2023TestJS Summit 2023
78 min
Mastering Node.js Test Runner
Workshop
Marco Ippolito
Marco Ippolito
Node.js test runner is modern, fast, and doesn't require additional libraries, but understanding and using it well can be tricky. You will learn how to use Node.js test runner to its full potential. We'll show you how it compares to other tools, how to set it up, and how to run your tests effectively. During the workshop, we'll do exercises to help you get comfortable with filtering, using native assertions, running tests in parallel, using CLI, and more. We'll also talk about working with TypeScript, making custom reports, and code coverage.

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

It's a Jungle Out There: What's Really Going on Inside Your Node_Modules Folder
Node Congress 2022Node Congress 2022
26 min
It's a Jungle Out There: What's Really Going on Inside Your Node_Modules Folder
Top Content
Do you know what’s really going on in your node_modules folder? Software supply chain attacks have exploded over the past 12 months and they’re only accelerating in 2022 and beyond. We’ll dive into examples of recent supply chain attacks and what concrete steps you can take to protect your team from this emerging threat.
You can check the slides for Feross' talk here.
Towards a Standard Library for JavaScript Runtimes
Node Congress 2022Node Congress 2022
34 min
Towards a Standard Library for JavaScript Runtimes
Top Content
You can check the slides for James' talk here.
Out of the Box Node.js Diagnostics
Node Congress 2022Node Congress 2022
34 min
Out of the Box Node.js Diagnostics
In the early years of Node.js, diagnostics and debugging were considerable pain points. Modern versions of Node have improved considerably in these areas. Features like async stack traces, heap snapshots, and CPU profiling no longer require third party modules or modifications to application source code. This talk explores the various diagnostic features that have recently been built into Node.
You can check the slides for Colin's talk here. 
ESM Loaders: Enhancing Module Loading in Node.js
JSNation 2023JSNation 2023
22 min
ESM Loaders: Enhancing Module Loading in Node.js
Native ESM support for Node.js was a chance for the Node.js project to release official support for enhancing the module loading experience, to enable use cases such as on the fly transpilation, module stubbing, support for loading modules from HTTP, and monitoring.
While CommonJS has support for all this, it was never officially supported and was done by hacking into the Node.js runtime code. ESM has fixed all this. We will look at the architecture of ESM loading in Node.js, and discuss the loader API that supports enhancing it. We will also look into advanced features such as loader chaining and off thread execution.
Node.js Compatibility in Deno
Node Congress 2022Node Congress 2022
34 min
Node.js Compatibility in Deno
Can Deno run apps and libraries authored for Node.js? What are the tradeoffs? How does it work? What’s next?
Javascript Should Come With Batteries
React Day Berlin 2023React Day Berlin 2023
30 min
Javascript Should Come With Batteries
Setting up JavaScript projects is no fun. Getting started involves installing and configuring node, tsc, prettier, eslint, a testing framework, a database driver, and more. Why is JavaScript not batteries included? In this talk we'll talk about how Deno fixes this, letting you focus on building stuff. We explore what benefits full tooling integration unlocks, and remember how fun it is to program if your tools help you, rather than requiring your babysitting.