Introducción a GraphQL: por qué necesitamos un nuevo tipo de API (Parte 1)

 

 

 

  • Patrones de diseño para interfaces de IA, con Vitaly Friedman
  • Planificación y proceso del sistema de diseño, con Nathan Curtis

  • Índice
    1. Introducción
    2. RPC
    3. JABÓN
    4. DESCANSAR
      1. Debilidades de REST
    5. Conclusión
      1. Otras lecturas

    En lugar de explorar las características primero, resulta útil ponerlas en contexto y comprender cómo llegaron a existir. En esta serie, Eric Baer quiere presentarle GraphQL. Al final, deberías entender qué es y también sus orígenes, sus inconvenientes y los conceptos básicos de cómo trabajar con él. Hoy, Eric repasará cómo y por qué llegamos a GraphQL analizando las lecciones aprendidas de los últimos 60 años de desarrollo de API, desde RPC hasta ahora.

     

    En esta serie, quiero presentarles GraphQL. Al final, deberías entender no sólo qué es, sino también sus orígenes, sus inconvenientes y los conceptos básicos de cómo trabajar con él. En este primer artículo, en lugar de saltar a la implementación, quiero repasar cómo y por qué llegamos a GraphQL (y herramientas similares) analizando las lecciones aprendidas de los últimos 60 años de desarrollo de API, desde RPC hasta ahora. Después de todo, como lo describió de manera colorida Mark Twain, no hay ideas nuevas.

    "No existe una idea nueva. Es imposible. Simplemente tomamos un montón de ideas viejas y las ponemos en una especie de caleidoscopio mental".

    — Mark Twain en "La propia autobiografía de Mark Twain: los capítulos de la revisión norteamericana"

    Pero primero tengo que dirigirme al elefante en la habitación. Las cosas nuevas siempre son emocionantes, pero también pueden resultar agotadoras. Es posible que haya oído hablar de GraphQL y haya pensado: "¿Por qué... ?" Alternativamente, tal vez haya pensado algo más como: "¿Por qué me importa una nueva tendencia de diseño de API? DESCANSAR está… bien”. Estas son preguntas legítimas, así que déjame ayudarte a explicar por qué deberías prestarle atención.

    Introducción

    Los beneficios de incorporar nuevas herramientas a su equipo deben sopesarse con sus costos. Hay muchas cosas que medir. Está el tiempo que lleva aprender, el tiempo que la conversión le quita al desarrollo de funciones y la sobrecarga de mantener dos sistemas. Con costos tan altos, cualquier tecnología nueva tiene que ser mejor, más rápida o mucho más productiva. Las mejoras incrementales, si bien son emocionantes, simplemente no valen la inversión. Los tipos de API de los que quiero hablar, GraphQL en particular, son en mi opinión un gran paso adelante y ofrecen beneficios más que suficientes para justificar el costo.

     

    En lugar de explorar las características primero, resulta útil ponerlas en contexto y comprender cómo llegaron a existir. Para hacer esto, comenzaré con un pequeño resumen de la historia de las API.

    RPC

    Podría decirse que RPC fue el primer patrón API importante y sus orígenes se remontan a la informática temprana a mediados de los años 60. En ese momento, las computadoras todavía eran tan grandes y costosas que la noción de desarrollo de aplicaciones impulsadas por API, tal como lo entendemos, era en gran medida meramente teórica. Limitaciones como el ancho de banda/latencia, la potencia de cálculo, el tiempo de cálculo compartido y la proximidad física obligaron a los ingenieros a pensar en términos de sistemas distribuidos en lugar de servicios que exponen datos. Desde ARPANET en los años 60, hasta mediados de los 90 con cosas como CORBA y RMI de Java, la mayoría de las computadoras interactuaban entre sí mediante llamadas a procedimientos remotos (RPC), que es un modelo de interacción cliente-servidor en el que un cliente provoca un procedimiento. (o método) para ejecutar en un servidor remoto.

    Hay muchas cosas buenas sobre RPC. Su principio fundamental es permitir que un desarrollador trate el código en un entorno remoto como si estuviera en uno local, aunque mucho más lento y menos confiable, lo que crea continuidad en sistemas que de otro modo serían distintos y dispares. Como muchas cosas que surgieron de ARPANET, se adelantó a su tiempo ya que este tipo de continuidad es algo por lo que todavía nos esforzamos cuando trabajamos con acciones asincrónicas y no confiables como el acceso a bases de datos y llamadas de servicios externos.

    A lo largo de las décadas, se ha realizado una enorme cantidad de investigaciones sobre cómo permitir a los desarrolladores incorporar un comportamiento asincrónico como este en el flujo típico de un programa; Si hubiera habido cosas como Promises, Futures y ScheduledTasks disponibles en ese momento, es posible que nuestro panorama de API se viera diferente.

    Otra gran ventaja de RPC es que, dado que no está restringido por la estructura de los datos, se pueden escribir métodos altamente especializados para los clientes que solicitan y recuperan exactamente la información necesaria, lo que puede resultar en una sobrecarga mínima de la red y cargas útiles más pequeñas.

    Sin embargo, hay cosas que dificultan la RPC. Primero, la continuidad requiere contexto . RPC, por diseño, crea bastante acoplamiento entre sistemas locales y remotos: se pierden los límites entre el código local y el remoto. Para algunos dominios, esto está bien o incluso es preferible, como en los SDK de clientes, pero para las API donde el código del cliente no se comprende bien, puede ser considerablemente menos flexible que algo más orientado a datos.

     

    Sin embargo, lo más importante es el potencial de proliferación de métodos API . En teoría, un servicio RPC expone una pequeña API que puede manejar cualquier tarea. En la práctica, se puede acumular una gran cantidad de puntos finales externos sin mucha estructura. Se necesita una enorme cantidad de disciplina para evitar la superposición de API y la duplicación con el tiempo a medida que los miembros del equipo van y vienen y los proyectos giran.

    Es cierto que con las herramientas y la documentación adecuadas se pueden gestionar cambios, como los que mencioné, pero mientras escribo software me he encontrado con unos pocos servicios disciplinados y de autodocumentación, por lo que, para mí, esto es un poco complicado. cortina de humo.

    JABÓN

    El siguiente tipo importante de API que apareció fue SOAP, que nació a finales de los 90 en Microsoft Research. SOAP ( S imple O bject A ccess P rotocol) es una especificación de protocolo ambiciosa para la comunicación basada en XML entre aplicaciones. La ambición declarada de SOAP era abordar algunos de los inconvenientes prácticos de RPC, XML-RPC en particular, creando una base bien estructurada para servicios web complejos. En efecto, esto sólo significó agregar un sistema de tipos de comportamiento a XML. Lamentablemente, creó más impedimentos de los que resolvió, como lo demuestra el hecho de que hoy en día se escriben muy pocos puntos finales SOAP nuevos.

    "SOAP es lo que la mayoría de la gente consideraría un éxito moderado".

    — Don Caja

    SOAP tenía algunas cosas buenas a su favor a pesar de su insoportable verbosidad y sus terribles nombres. Los contratos ejecutables en WSDL y WADL (pronunciados “wizdle” y “waddle”) entre el cliente y el servidor garantizaban resultados predecibles y con seguridad de tipos, y el WSDL podía usarse para generar documentación o crear integraciones con IDE y otras herramientas.

    La gran revelación de SOAP con respecto a la evolución de API fue su introducción gradual y posiblemente involuntaria de llamadas más orientadas a recursos. Los puntos finales SOAP le permiten solicitar datos con una estructura predeterminada en lugar de pensar en los métodos necesarios para generar los datos (suponiendo que estén escritos de esta manera).

    La desventaja más importante de SOAP es que es muy detallado; es casi imposible de usar sin muchas herramientas . Necesita herramientas para escribir pruebas, herramientas para inspeccionar las respuestas de un servidor y herramientas para analizar todos los datos. Muchos sistemas más antiguos todavía usan SOAP, pero los requisitos de herramientas lo hacen demasiado engorroso para la mayoría de los proyectos nuevos, y la cantidad de bytes necesarios para la estructura XML lo convierte en una mala opción para atender dispositivos móviles o sistemas distribuidos conversacionales.

    Para obtener más información, vale la pena leer las especificaciones de SOAP , así como la historia sorprendentemente interesante de SOAP de Don Box, uno de los miembros originales del equipo.

     

    DESCANSAR

    Finalmente, hemos llegado al patrón de diseño de API del día: REST. REST, introducido en una tesis doctoral de Roy Fielding en 2000, hizo girar el péndulo en una dirección completamente diferente. REST es, en muchos sentidos, la antítesis de SOAP y mirarlos uno al lado del otro te hace sentir como si su disertación fuera un poco furiosa.

    SOAP utiliza HTTP como transporte tonto y construye su estructura en el cuerpo de solicitud y respuesta. REST, por otro lado, descarta los contratos cliente-servidor, herramientas, XML y encabezados personalizados, reemplazándolos con semántica HTTP como estructura, eligiendo en su lugar usar verbos HTTP para interactuar con datos y URI que hacen referencia a un recurso en alguna jerarquía de datos.

    JABÓN DESCANSAR
    Verbos HTTP OBTENER, PONER, PUBLICAR, PARCHEAR, BORRAR
    Formato de datos XML Lo que quieras
    Contratos Cliente/Servidor ¡Todo el día, todos los días! ¿Quién necesita esos?
    Tipo de sistema JavaScript tiene un corto sin firmar, ¿verdad?
    URL Describir operaciones Recursos nombrados

    REST cambia completa y explícitamente el diseño de API desde el modelado de interacciones hasta el simple modelado de los datos de un dominio. Al estar totalmente orientado a los recursos cuando se trabaja con una API REST, ya no es necesario saber ni preocuparse por lo que se necesita para recuperar un determinado dato; ni es necesario que sepa nada sobre la implementación de los servicios backend. Blog sobre psicologia

    La simplicidad no solo fue una bendición para los desarrolladores, sino que, dado que las URL representan información estable, se pueden almacenar en caché fácilmente, su falta de estado facilita su escalamiento horizontal y, dado que modela los datos en lugar de anticipar las necesidades de los consumidores, puede reducir drásticamente el área de superficie de las API. .

    REST es fantástico y su ubicuidad es un éxito asombroso, pero, como todas las soluciones anteriores, REST no está exento de defectos. Para hablar concretamente de algunas de sus carencias repasemos un ejemplo básico. Supongamos que tenemos que crear la página de inicio de un blog que muestra una lista de publicaciones del blog y el nombre de su autor.

    La página de inicio de un blog básico que muestra el título y el autor de cada publicación. ( vista previa grande)

    Escribamos el código que pueda recuperar los datos de la página de inicio desde una API REST simple. Comenzaremos con algunas funciones que envuelven nuestros recursos.

    const getPosts = () = fetch(`${API_ROOT}/posts`);const getPost = postId = fetch(`${API_ROOT}/posts/${postId}`);const getAuthor = authorId = fetch(`${API_ROOT}/authors/${authorId}`);

    ¡Ahora vamos a orquestar!

    const getPostWithAuthor = postId = { return getPost(postId) .then(post = getAuthor(post.author)) .then(author = { return Object.assign({}, post, { author }) })};const getHomePageData = () = { return getPosts() .then(postIds = { const postDetails = postIds.map(getPostWithAuthor); return Promise.all(postDetails); })};

    Entonces nuestro código hará lo siguiente:

     

    • Obtener todas las publicaciones;
    • Obtenga los detalles de cada publicación;
    • Obtener recurso de autor para cada publicación.

    Lo bueno es que es bastante fácil razonar sobre esto, está bien organizado y los límites conceptuales de cada recurso están bien trazados. Lo malo aquí es que acabamos de realizar ocho solicitudes de red, muchas de las cuales ocurren en serie.

    GET /postsGET /posts/234GET /posts/456GET /posts/17GET /posts/156GET /author/9GET /author/4GET /author/7GET /author/2

    Sí, se podría criticar este ejemplo sugiriendo que la API podría tener un /postspunto final paginado, pero eso es muy delicado. El hecho es que a menudo hay una colección de llamadas API que dependen unas de otras para representar una aplicación o página completa.

    Desarrollar clientes y servidores REST es ciertamente mejor que lo anterior, o al menos más a prueba de idiotas, pero muchas cosas han cambiado en las dos décadas transcurridas desde el artículo de Fielding. En ese momento, todas las computadoras eran de plástico beige; ¡Ahora son de aluminio! En serio, el año 2000 estuvo cerca del pico de la explosión de la informática personal. Cada año, los procesadores duplicaban su velocidad y las redes se hacían más rápidas a un ritmo increíble. La penetración de Internet en el mercado rondaba el 45% y no había otro lugar adonde ir que subir.

    Luego, alrededor de 2008, la informática móvil se generalizó. Con los dispositivos móviles, efectivamente retrocedimos una década en términos de velocidad/rendimiento de la noche a la mañana. En 2017, tenemos casi un 80% de penetración de teléfonos inteligentes a nivel nacional y más del 50% a nivel mundial, y es el momento de repensar algunas de nuestras suposiciones sobre el diseño de API.

    Debilidades de REST

    La siguiente es una mirada crítica a REST desde la perspectiva de un desarrollador de aplicaciones cliente, particularmente uno que trabaja en dispositivos móviles. Las API GraphQL y estilo GraphQL no son nuevas y no resuelven problemas que están fuera del alcance de los desarrolladores REST. La contribución más importante de GraphQL es su capacidad para resolver estos problemas de forma sistemática y con un nivel de integración que no está disponible en otros lugares. Es decir, es una solución “pilas incluidas”.

    Los autores principales de REST, incluido Fielding, publicaron un artículo a finales de 2017 ( Reflexiones sobre el estilo arquitectónico REST y “Diseño de principios de la arquitectura web moderna” ) que reflexiona sobre dos décadas de REST y los numerosos patrones que ha inspirado. Es breve y vale la pena leerlo para cualquier persona interesada en el diseño de API.

    Con algo de contexto histórico y una aplicación de referencia, veamos las tres debilidades principales de REST.

    REST es hablador

    Los servicios REST tienden a ser al menos algo “conversadores”, ya que se necesitan múltiples viajes de ida y vuelta entre el cliente y el servidor para obtener suficientes datos para representar una aplicación. Esta cascada de solicitudes tiene impactos devastadores en el rendimiento, especialmente en dispositivos móviles. Volviendo al ejemplo del blog, incluso en el mejor de los casos, con un teléfono nuevo y una red confiable con una conexión 4G, ha gastado casi 0,5 segundos en sobrecarga de latencia antes de que se descargue el primer byte de datos.

     

    * Latencia 4G de 55 ms * 8 solicitudes = 440 ms de sobrecarga *

    Un gráfico que describe la respuesta del usuario a varios niveles de rendimiento de la aplicación. (Crédito de la imagen: Redes de navegador de alto rendimiento ) ( Vista previa grande )

    Otro problema con los servicios de conversación es que en muchos casos lleva menos tiempo descargar una solicitud grande que muchas pequeñas. El rendimiento reducido de las solicitudes pequeñas se debe a muchas razones, incluido el inicio lento de TCP, la falta de compresión de encabezados y la eficiencia de gzip. Si tiene curiosidad, le recomiendo leer High-Performance Browser Networking de Ilya Grigorik . El blog de MaxCDN también tiene una excelente descripción general.

    Este problema no es técnicamente con REST sino con HTTP, específicamente HTTP/1. HTTP/2 prácticamente resuelve el problema de la conversación independientemente del estilo de API y tiene un amplio soporte en clientes como navegadores y SDK nativos. Desafortunadamente, la implementación ha sido lenta en el lado de la API. Entre los 10.000 sitios web principales, la adopción es de alrededor del 20 % (y está aumentando) a finales de 2017. Incluso Node.js, para mi sorpresa, obtuvo soporte HTTP/2 en su versión 8.x. Si tiene la capacidad, ¡actualice su infraestructura! Mientras tanto, no nos detengamos ya que esto es sólo una parte de la ecuación.

    Dejando a un lado HTTP, la última parte de por qué es importante la conversación tiene que ver con cómo funcionan los dispositivos móviles, y específicamente sus radios. En resumen, operar la radio es una de las partes de un teléfono que consume más batería, por lo que el sistema operativo la apaga en cada oportunidad. Encender la radio no sólo agota la batería, sino que añade aún más gastos generales a cada solicitud.

    TMI (sobrecarga)

    El siguiente problema con los servicios de estilo REST es que envían mucha más información de la necesaria. En nuestro ejemplo de blog, todo lo que necesitamos es el título de cada publicación y el nombre de su autor, que es solo aproximadamente el 17% de lo que se devolvió. Esa es una pérdida 6x para una carga útil muy simple. En una API del mundo real, ese tipo de gastos generales pueden ser enormes. Los sitios de comercio electrónico, por ejemplo, suelen representar un único producto como miles de líneas de JSON. Al igual que el problema de la charla, los servicios REST pueden manejar este escenario hoy usando "conjuntos de campos dispersos" para incluir o excluir condicionalmente partes de los datos. Desafortunadamente, el soporte para esto es irregular, incompleto o problemático para el almacenamiento en caché de la red.

    Herramientas e introspección

    Lo último que les falta a las API REST son mecanismos de introspección. Sin ningún contrato con información sobre los tipos de retorno o la estructura de un punto final, no hay forma de generar documentación, crear herramientas o interactuar con los datos de manera confiable. Es posible trabajar dentro de REST para resolver este problema en diversos grados. Los proyectos que implementan completamente OpenAPI, OData o JSON API suelen ser limpios, bien especificados y, en diversos grados, bien documentados, pero backends como este son raros. Incluso los hipermedia, una fruta relativamente fácil de conseguir, a pesar de haber sido promocionada en conferencias durante décadas, todavía no se hace bien, si es que se hace en absoluto.

    Conclusión

    Cada uno de los tipos de API tiene fallas, pero todos los patrones también lo son. Este escrito no es un juicio sobre el fenomenal trabajo que los gigantes del software han sentado, sino sólo una evaluación sobria de cada uno de estos patrones, aplicados en su forma “pura” desde la perspectiva de un desarrollador cliente. Espero que, en lugar de dejar de pensar que un patrón como REST o RPC está roto, usted pueda salir pensando en cómo cada uno de ellos hizo concesiones y en las áreas en las que una organización de ingeniería podría centrar sus esfuerzos para mejorar sus propias API .

    En el próximo artículo , exploraré GraphQL y cómo pretende abordar algunos de los problemas que mencioné anteriormente. La innovación en GraphQL y herramientas similares está en su nivel de integración y no en su implementación. Por favor, si usted o su equipo no están buscando una API con “baterías incluidas”, considere buscar algo como la nueva especificación OpenAPI que puede ayudar a construir una base más sólida hoy.

    Si disfrutó este artículo (o si lo odió) y desea enviarme su opinión, encuéntreme en Twitter como @ebaerbaerbaer o LinkedIn en ericjbaer .

    Otras lecturas

    • Una guía para el kit de herramientas Redux con TypeScript
    • Knip: una herramienta automatizada para buscar archivos, exportaciones y dependencias no utilizados
    • Estilo de control de formulario avanzado con menú de selección y API de anclaje
    • Por qué debería considerar los gráficos para su próximo proyecto GraphQL

    (rb, ra, yk, il, mrn)Explora más en

    • javascript
    • API
    • GrafoQL





    Tal vez te puede interesar:

    1. ¿Deberían abrirse los enlaces en ventanas nuevas?
    2. 24 excelentes tutoriales de AJAX
    3. 70 técnicas nuevas y útiles de AJAX y JavaScript
    4. Más de 45 excelentes recursos y repositorios de fragmentos de código

    Introducción a GraphQL: por qué necesitamos un nuevo tipo de API (Parte 1)

    Introducción a GraphQL: por qué necesitamos un nuevo tipo de API (Parte 1)

    Patrones de diseño para interfaces de IA, con Vitaly Friedman Planificación y proceso del sistema de diseño, con Nathan Curtis Índice

    programar

    es

    https://aprendeprogramando.es/static/images/programar-introduccion-a-graphql-por-que-necesitamos-un-nuevo-tipo-de-api-parte-1-924-0.jpg

    2024-05-20

     

    Introducción a GraphQL: por qué necesitamos un nuevo tipo de API (Parte 1)
    Introducción a GraphQL: por qué necesitamos un nuevo tipo de API (Parte 1)

    Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

     

     

    Top 20