Conexión HTTP cliente-servidor con TypeScript

0
4616

Antes de empezar recordar que este tutorial forma parte de una cadena de tutoriales en las que pretendo simplemente probar tecnologías actuales. Aquí abajo podrás encontrarlos :

 

También  me gustaría que vieras este video de 2 minutos para entender dónde estamos y a dónde vamos


Mi equipo es Mac

macOS Catalina
Versión 10.15.2

MacBook Pro (15-inch, 2018)
Procesador 2,9 GHz Intel Core i9 de 6 núcleos
Memoria 32 GB 2400 MHz DDR4
Gráficos Intel UHD Graphics 630 1536 MB


Si queremos hacer un juego y mostrar/guardar los mejores resultados de los jugadores tendremos que almacenarlos en un servidor central.

Hay muchos modos de hacerlo y vamos a probar ahora el más sencillo (que no es el definitivo pero hemos dicho que el objetivo es aprender las bases), que es que el servidor http nos retorne una respuesta JSON y que el cliente, nuestro programa TypeScript, lo muestre por pantalla.

Lo primero que vamos a aprender a hacer es una petición HTTP en TypeScript básica.

Para ello tenemos que poder instalar los comandos http de node/JavaScript por los que con npm instalamos. Esta es la secuencia que voy a ejecutar.

npm i @types/node

npm install acorn

npm audit fix

 

Realmente quería instalar @types para tener acceso a los tipos básicos.

Al leer el log he visto que daba errores y requería la instalación manual de acorn.

Al instalar el último paquete he visto que había vulnerabilidades y he ejecutado fix.

Esta es la salida de la pantalla de la secuencia.

Hay un dicho “si veo lejos es porque me apoyo en hombres de gigantes” (creo que de Newton) así que buscando en internet he encontrado este interesante tutorial, que usa servicios de la NASA, para ver cómo hacer la comunicación cliente/servidor.

https://www.twilio.com/blog/2017/08/http-requests-in-node-js.html.

Vamos a usar ese servicio para jugar.

Simplemente vamos a probar (corrigiendo errores simples porque faltan tipos) y podemos ver la respuesta de la NASA.

Funciona, pero de momento no me es demasiado satisfactorio, porque voy a tratar de usar librerías y usar clases que me hagan todo más sencillo para hacerlo un poco más TypeScript.

Seguiremos este guion:

– Vamos a aprender a hacer peticiones al servidor sin programar, usando programas que nos lo faciliten y monitorizando lo que pasa, incluso que nos generen el código.

– Luego vamos a crear objetos TypeScript y vincularles la respuesta JSON obtenida de un modo asíncrono.

– Finalmente veremos un modo alternativo de conectarnos sincronamente (con fetch y promesas).

Empezamos con programas para hacer peticiones. Un herramienta muy fácil de usar para hacer peticiones HTTP es https://reqbin.com/

Podemos ver mejor la respuesta que nos ha dado la NASA.

{

    «date»: «2020-01-27»,

    «explanation»: «Where do comet tails come from?  There are no obvious places on the nuclei of comets from which the jets that create comet tails emanate.  One of the best images of emerging jets is shown in the featured picture, taken in 2015 by ESA’s robotic Rosetta spacecraft that orbited Comet 67P/Churyumov-Gerasimenko (Comet CG) from 2014 to 2016.  The picture shows plumes of gas and dust escaping numerous places from Comet CG’s nucleus as it neared the Sun and heated up.  The comet has two prominent lobes, the larger one spanning about 4 kilometers, and a smaller 2.5-kilometer lobe connected by a narrow neck. Analyses indicate that evaporation must be taking place well inside the comet’s surface to create the jets of dust and ice that we see emitted through the surface.  Comet CG (also known as Comet 67P) loses in jets about a meter of radius during each of its 6.44-year orbits around the Sun, a rate at which will completely destroy the comet in only thousands of years. In 2016, Rosetta’s mission ended with a controlled impact onto Comet CG’s surface.   Outreach Astronomers: Future APOD writers sought.»,

    «hdurl»: «https://apod.nasa.gov/apod/image/2001/Comet67P_Rosetta_1024.jpg»,

    «media_type»: «image»,

    «service_version»: «v1»,

    «title»: «Comet CG Evaporates»,

    «url»: «https://apod.nasa.gov/apod/image/2001/Comet67P_Rosetta_1024.jpg»

}

Pero también podemos hacer otro tipo de peticiones.

De este modo sencillo separamos dos problemas, la programación de front y de back y simplemente negociamos la interfaz (luego nos tendríamos que preocupar de la seguridad).

Otra herramienta que podemos utilizar para el mismo propósito, bastante más avanzada, es Postman https://www.getpostman.com/

Yo investigaría un poco más sobre las capacidades de esta herramienta a la hora de probar y construir juegos de pruebas de APIs (ahí lo dejo).

En mi caso, como sólo estoy haciendo un tutorial voy a usar la versión experimental de PostMan:  https://www.getpostman.com/downloads/canary

Creamos nuestra cuenta o nos logamos con una existente.

Al contestar el correo electrónico de confirmación de cuenta de correo nos salta a la página Web. Aprovechad y navegad un poco por las APIs que encontrareis.

Si pincháis en API Evangelist podréis encontrar algunas para jugar, como la de la NASA:

Dentro de estas 4 APIs disponible y la última es la de la NASA.

Decimos de ejecutarla en Postman local, el programa que hemos instalado.

Este es el aspecto de la primera pantalla de Postman.

Si vamos a la lengüeta de Collections encontramos la que hemos descargado.

Ahora podemos ver todas las posibles peticiones (79) y vemos que nos genera una URL (incompleta, ya que falta la clave para usar el API que proporciona el servidor de la misma).

Vamos a la página Web de la NASA ya por curiosidad y vemos la descripción de la API en https://api.nasa.gov/

Podéis registrar vuestra clave o seguir usando la de demo, tal como explica en las instrucciones. Es interesante que leáis sobre las limitaciones de uso.

Cambiamos la URL para poner la Key de Demo y damos enviar (SEND).

La respuesta podemos comprobar que es un documento JSON.

Mirad que buena gente que hasta te crea el código (SNIPPETS), en distintos lenguajes, que necesitas para hacer la invocación.

Este es nuestro código generado por la herramienta:

var request = require('request');

var options = {

  'method': 'GET',

  'url': 'https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY&date=2019-09-13&hd=true',

  'headers': {

  }

};

request(options, function (error, response) {

  if (error) throw new Error(error);

  console.log(response.body);

});

Lo podemos ejecutar en nuestro proyecto base sin cambiar nada.

Ahora vamos a modificar el código de nuestro proyecto y comprender algunos problemas con la ejecución asíncrona.

Paraos a mirar: hacemos la petición GET, se invoca una función y el programa sigue. Si retornamos el valor de propiedades de la clase no están todavía actualizadas.

Este es todo el código.

let request = require("request");

class GestorNoticiasNASA {
  peticion: any = null;
  respuesta: any = "todavía Nada";
  URL: string = "";

  constructor(URL: string) {
    this.URL = URL;
  }

  anima = (error: any, response: any) => {
    if (error) {
      throw new Error(error);
    } else {
      console.log("----------- Dentro de la función --------------");
      console.log(response.body);
      this.respEst = response.body;

      console.log("----------- Estructura --------------");
      console.log(this.respEst);
    }
  };

  recupera() {
    //creamos estructura
    let options = {
      method: "GET",
      url: this.URL,
      headers: {}
    };

    this.peticion = request(options, this.anima);
    console.log("----------- Despues de la función --------------");
    console.log(this.respuesta);
  }
}

let gestorNASA = new GestorNoticiasNASA(
  "https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY&date=2019-09-13&hd=true"
);

gestorNASA.recupera();
console.log("----------- Fuera de la función--------------");
console.log(gestorNASA.respuesta);

for (var i = 0; i < 5; i++) {
  setTimeout(function() {
    console.log(new Date()); //It's you code
  }, (i + i + 1) * 1000);
}

console.log("-----------final del retraso asincrono --------------");
console.log(gestorNASA.respuesta);

Fijaros en los mensajes de log.

Esto no será relevante si actualizamos elementos de la página Web que no requieran comportamientos síncronos.

Vamos a hacer un pequeño cambio para ver como poder manipular la respuesta como un objeto TypeScript, mediante un interfaz, y el comando JSON.parse(string).

Usaremos la interfaz para filtrar los campos que queremos recuperar.

Fijaros en esta línea en concreto:       console.log(objeto.copyright);

Este es el código de nuestro proyecto.

let request = require("request");

interface INoticiaNasa {
  copyright: string;
  date: string;
  explanation: string;
  hdurl: string;
  media_type: string;
  service_version: string;
  title: string;
  url: string;
}

class GestorNoticiasNASA {
  peticion: any = null;
  URL: string = "";

  constructor(URL: string) {
    this.URL = URL;
  }

  anima = (error: any, response: any) => {
    if (error) {
      throw new Error(error);
    } else {
      let objeto: INoticiaNasa = JSON.parse(response.body);
      console.log(objeto.copyright);
    }
  };

  recupera() {
    let options = { method: "GET", url: this.URL, headers: {} };

    this.peticion = request(options, this.anima);
  }
}

let gestorNASA = new GestorNoticiasNASA(
  "https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY&date=2019-09-13&hd=true"
);

gestorNASA.recupera();

Si queremos comportamientos síncronos tendremos que utilizar otros sistemas. El API de fetch, compatible con muchos navegadores, combinado con una técnica llamada promesas, nos permite el comportamiento que deseamos.

Os invito a visitar este enlace. https://www.todojs.com/api-fetch-el-nuevo-estandar-que-permite-hacer-llamadas-http/

El código JavaScript para utilizar fetch es muy sencillo.

Compilamos y lanzamos con Parcel.

Y al ejecutar podemos ver volcada la respuesta en la pantalla y podríamos tener el comportamiento síncrono en caso de desearlo.

No vamos a avanzar más con el ejemplo porque ahora nos interesa más FireBase.

 

Aquí te dejo el siguiente tutorial.

Cursores múltiples y otras opciones y extensiones sencillas y útiles en Visual Studio Code

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad