Llegamos a ustedes gracias a:



Reportajes y análisis

¿Qué es una API?

Las interfaces de programación de aplicaciones explicadas

[08/09/2022] El término API significa interfaz de programación de aplicaciones, un concepto que se aplica en todas partes, desde herramientas de línea de comandos hasta código empresarial, microservicios y arquitecturas nativas de la nube. Una API es una interfaz que los desarrolladores de software utilizan para interactuar mediante programación con componentes o recursos de software fuera de su propio código. Una definición aún más simple es que una API es la parte de un componente de software que es accesible a otros componentes.

A menos que escriba cada línea de código desde cero, interactuará con componentes de software externos y cada uno de estos tendrá su propia API. Incluso si escribe todo el código desde cero, una aplicación bien diseñada debería tener varias API internas para ayudar a organizar el código y hacer que sus componentes sean más reutilizables.

[Reciba lo último de CIO Perú suscribiéndose a nuestro newsletter semanal]

La API es un concepto clave en el desarrollo de software, desde programas simples hasta las consideraciones más avanzadas de diseño y arquitectura. Este artículo le ayudará a entender las API y cómo se utilizan en el desarrollo de software.

Las API en el desarrollo de software

Una API es la parte de un programa de software que es accesible a otros programas. Es el área externa de un componente de software. Por este motivo, es posible que vea una referencia a la superficie de la API de un programa. La superficie de la API es la capa exterior del programa o componente, como la pared de una célula, tal y como se muestra en la Figura 1.

API, interface de programación de aplicaciones
Figura 1. Un componente de aplicación con su API.

Cuando un programa es utilizado por otro programa, llamamos al primer programa el proveedor y al segundo el cliente. La parte del proveedor que es accesible para los clientes es la API. Esta disposición se encuentra en aplicaciones y sistemas de software de casi todos los tipos. Lo que es consistente es que la API es una forma en la que los clientes hacen llamadas al proveedor. La API define un rango conocido de inputs permitidos y outputs asociados al componente. Por lo tanto, la API define el protocolo de comunicación con un componente.

Todo el software, excepto el más trivial, utiliza capacidades proporcionadas por otros componentes. Un programa de software llama a la API de un componente para acceder a sus capacidades. Además de usar otros componentes, la mayoría del software se usa como componente de otros programas, tal y como se muestra en la Figura 2.

Figura 2. Múltiples componentes interactuando a través de sus API.
API, interfase programación aplicaciones

API vs. UI

Es posible que se observen algunas similitudes entre las API y las interfaces de usuario o UI. Esto tiene sentido porque ambas son interfaces. Una interfaz es un medio para interactuar con las partes internas de un sistema. Generalmente, el trabajo de la interfaz es simplificar y concentrar las capacidades internas en una forma que sea útil para el cliente. La diferencia entre las API y las UI es que interactúan con diferentes tipos de clientes.

En una laptop, la interfaz de usuario consta de dispositivos de entrada, como un teclado y un mouse; y dispositivos de salida, como un monitor y un teclado. El cliente es la persona que usa la laptop. Además del sistema operativo, muchos de los programas que se ejecutan en esa laptop también presentan una interfaz de usuario, con la que el usuario puede interactuar a través de los dispositivos de entrada y salida. Por ejemplo, el navegador web presenta un conjunto de elementos visuales en la pantalla que se pueden controlar con el mouse y el teclado.

La API del navegador: Pensemos en ese navegador web. Sabemos que un navegador se utiliza para abrir una variedad de páginas web. La mayoría de las páginas web cargan JavaScript como parte de su estructura. El navegador ejecuta JavaScript para ayudar a mostrar la página. Para funcionar, el programa JavaScript requiere acceso a las capacidades del navegador. En este caso, el programa JavaScript es el cliente de la API y el navegador es el proveedor de la API. El navegador es un proveedor que ofrece capacidades de navegación web a las que accede el programa JavaScript a través de una interfaz de programación, la API del navegador.

Por ejemplo, si presiona F12 en este momento y abre una consola de JavaScript, puede escribir un pequeño programa de JavaScript para interactuar con la API de su navegador. Si introduce el código en el Listado 1 en la consola, comenzará a ver output.

Listado 1. Seguimiento del mouse en la consola del navegador

window.onmousemove = function(e){console.log("mouse cursor:", e.clientX, e.clientY)}

Tenga en cuenta que después de que comience a ver el output de la consola, puede desactivar esta configuración ingresando:

window.onmousemove = null

El punto de este ejemplo es que el objeto ventana es parte de la API del navegador. Además, la función (o método) onmousemove es un miembro del objeto ventana. A su vez, forma parte de la API del objeto ventana. Entonces, una vez que esté en el código, puede comenzar a ver que las API están en todas partes. Si desea utilizar la funcionalidad de un componente, puede acceder a ella a través de la API del componente.

API anidadas: Otra observación es que las API existen en diferentes niveles de un programa y se contienen entre sí. La API de la ventana está, en cierto sentido, anidada dentro de la API del navegador. 

Ahora analicemos un poco más a profundidad la forma en que el navegador hace su trabajo. Esto nos ayudará a familiarizarnos con un par de otros tipos de API. Por un lado, ¿cómo el navegador conoce la posición del mouse? Se registra con el sistema operativo a través de una API. Luego, el sistema operativo carga un controlador de mouse que ofrece una API estandarizada para proporcionar información de transmisión sobre lo que está haciendo el mouse. (El controlador en sí, si sigue investigando, en última instancia se basa en interfaces de hardware y software de bajo nivel, un tercer tipo de interfaz junto con UI y API).

API en bibliotecas, paquetes y módulos: La consola del navegador es un contexto especializado en el que todas las bibliotecas están precargadas por el entorno de tiempo de ejecución. Es más común que el programador cargue explícitamente las bibliotecas. La forma en que ocurre la carga varía según el lenguaje de programación, pero cada vez que vea los términos importar, incluir o requerir en su salida, significa que el programa actual está extrayendo la API de otro programa.

Todos los programas, excepto los más triviales, consisten en expresiones y construcciones a nivel de idioma (como ifs, bucles y operadores) que se usan junto con llamadas a las API que se encuentran en otros paquetes. A su vez, cada programa es también un componente que puede ser incluido y utilizado por otros programas.

En términos generales, los módulos, paquetes y bibliotecas tienen el mismo concepto: son colecciones de código que pueden incluirse. La suma de sus partes visibles públicamente (clases, objetos, métodos, funciones, variables, etc.) es el área superficial de la API de esa colección.

Las API en la programación funcional y orientada a objetos: Los paradigmas programáticos como la programación orientada a objetos y la programación funcional adoptan diferentes enfoques para facilitar el desarrollo de buenas API. La programación orientada a objetos fomenta una fuerte encapsulación, mientras que la programación funcional expone la funcionalidad para facilitar el flujo de código.

API remotas y microservicios: En el más alto nivel, podríamos dividir las API en dos tipos: locales y remotas. Las API remotas son útiles porque no requieren actualizaciones del código en los dispositivos de los clientes, se pueden escalar de manera independiente y presentan un formulario de API estandarizado al que cualquier cliente puede llamar siempre que esté autorizado.

En general, podríamos decir que las API remotas (también conocidas como servicios) están fuertemente desacopladas y ofrecen un protocolo estándar (HTTP/S sobre TCP) que funciona independientemente de la pila de implementación que haya detrás.

Configuremos una interacción rápida con una API remota. Nuevamente en su consola de JavaScript, ingrese el código del Listado 2.

Listado 2. Llamadas a la API del Señor de los Anillos

const fetchData = async () => {
  const rawQuotes = await  fetch('https://the-one-api.dev/v2/quote', {
  headers: {
    'Accept': 'application/json',
    'Authorization': 'Bearer xvi06TocPJvBmrQC4yZv'
  }
})

  const quotes = await rawQuotes.json();
  const quote = quotes.docs[Math.floor(Math.random() *  quotes?.docs?.length)];

  const rawCharacters = await   fetch('https://the-one-api.dev/v2/character?_id=' + quote.character, { headers: headers })
  const characters = await rawCharacters.json();
  const character = characters.docs[0];
  console.log(character.name + " said: " + quote.dialog);
};

fetchData();

Si ejecuta este código, obtendrá un registro de la consola. Lo que ocurre es que usted ha creado un programa de JavaScript que ha utilizado la API del navegador (específicamente, la Fetch API) para realizar una llamada HTTP contra el servidor que vive en https://the-one-api.dev. Esa es una API REST, lo que significa que sigue ciertas convenciones arquitectónicas.

Microservicios y puertas de enlace de API: Una arquitectura de microservicios utiliza esencialmente API remotas para actividades que tradicionalmente se realizaban mediante API locales. Una arquitectura de microservicios descompone una aplicación en componentes que están disponibles de forma remota.

El concepto de una puerta de enlace de API es específico de la arquitectura de microservicios. En una puerta de enlace de API se define un único punto de contacto en la red para orquestar rutas a servicios específicos. Esto permite ciertos beneficios (como la autenticación y la limitación de velocidad entre servicios) y funciona como una especie de interfaz de interfaces.

Las API remotas están en todas partes: Internet es básicamente un universo de API remotas que interactúan. Todo lo que se ejecuta en un dispositivo es una API local. Los servidores son colecciones de API locales que conspiran para proporcionar una API remota. Los clientes son colecciones de API locales que funcionan juntas para consumir API remotas. El middleware es una colección de API locales que conspiran para proporcionar una API remota y trabajan juntas para consumir otras API remotas.

API y buen diseño de software

En todas las plataformas y lenguajes, hay diferentes formas de controlar lo que es visible y cómo lo utiliza el código del cliente. El diseño de las API presta mucha atención a la idea de ocultar información, que es el eje del software sostenible. Un buen diseño de software depende de ello.

La idea es escribir componentes de software que hagan todo lo que se les pide con el menor punto de contacto posible. Como desarrolladores, queremos proporcionar solo la información más esencial sobre el funcionamiento interno de un componente. Este concepto se aplica a todo, desde una pequeña función -cuya firma es una API en letra pequeña- hasta potentes servicios remotos.

Separación de intereses: A veces se dice que un buen componente es una "caja negra, que significa que el componente lleva a cabo su trabajo sin revelar cómo lo hace. La caja negra representa el ideal de la separación de intereses, y contrasta con la caja blanca, donde los clientes deben saber lo que sucede dentro del componente para usarlo. En un escenario de caja blanca, tanto el conocimiento como la complejidad se esparcen o se filtran. En realidad, todos los componentes son cajas grises. Como desarrolladores de software, intentamos que sean lo más grises posible.

Las buenas API son lo opuesto al código espagueti. En el código espagueti, el flujo de ejecución y dependencia es muy difícil de seguir, lo que hace que el código sea difícil de mantener y depurar. (Es por eso que GOTO se considera dañino).

En un buen diseño de API, los componentes de software se comportan como componentes mecánicos. Realizan un trabajo particular detrás de una interfaz bien entendida. Se puede tratar el componente como una sola entidad. El alternador de un automóvil hace una cosa: crea una carga. Si falla, el mecánico puede aislar esa parte. Igual de importante, el resto del automóvil solo necesita saber que la correa gira alrededor de la polea del alternador. En esta analogía, la polea y los terminales eléctricos del alternador serían el API del alternador.

Por supuesto, el aislamiento nunca es perfecto. Incluso en el caso de un alternador, la condición de la correa y el tensor interactúan de manera importante. Los desarrolladores intentan crear buenos componentes, subsistemas y arquitecturas. Lo hacemos para controlar a los principales antagonistas del software: las fuerzas de la entropía y la complejidad.

Concentrar la complejidad en los componentes y simplificar al máximo sus interfaces y protocolos hace que nuestros sistemas de software sean mucho más fáciles de gestionar.

API e interfaces explícitas: Los lenguajes de programación como Java, Python y C++ tienen una construcción de interfaz explícita, que brinda soporte a nivel de lenguaje para las API. La interfaz define una API sin ningún detalle de implementación, por lo que se pueden implementar una o más clases concretas. Todos los implementadores deben respetar la interfaz, pero pueden diferir en la forma en que logran la funcionalidad.

Conclusión

Las API son esenciales para un buen diseño de software y asumen una serie de encarnaciones en las diferentes capas de nuestro software. A la hora de escribir software, es valioso pensar en el código que está escribiendo como un componente, potencialmente reutilizable en otros sistemas. Tenga en cuenta las características de la API de su componente. Si lo hace, probablemente se centrará en un conjunto limitado de funciones y pensará en cómo la superficie de la API interactuará con otros componentes. Piense en términos de separación de intereses e intente exponer solo la información estrictamente necesaria sobre su componente.

El uso de API bien diseñadas nos permite formular nuestro software de componentes lógicamente distintos. Estos componentes pueden mantenerse en relativo aislamiento y la funcionalidad que hay detrás puede reutilizarse entre diferentes aplicaciones.

Crédito foto: Cetin Aydin / CC0)

Puede ver también: