¿Por qué las API de AWS devuelven XML? - La historia de la evolución desde Query API hasta REST JSON
Explicamos las razones históricas por las que las API de S3 y EC2 devuelven respuestas XML, las diferencias entre Query API y REST API, la evolución de la autenticación de Signature V2 a V4, y la complejidad que los SDK ocultan.
El diseño de API en 2006 - Una era donde XML era lo natural
Cuando S3 y EC2 se lanzaron en 2006, XML era el formato de datos estándar en el mundo de las Web API. SOAP (Simple Object Access Protocol) era la corriente principal de los servicios web empresariales, y la definición estricta de tipos mediante XML Schema y la descripción de servicios mediante WSDL (Web Services Description Language) se consideraban el diseño de API "correcto". JSON es un formato ligero propuesto por Douglas Crockford a principios de la década de 2000, pero en 2006 aún no estaba ampliamente difundido y se evaluaba como "ligero pero carente de seguridad de tipos". Las primeras API de AWS reflejan la filosofía de diseño de aquella época. La API de EC2 utiliza un formato llamado "Query API", en el que el nombre de la acción y los parámetros se especifican como parámetros de consulta de una solicitud HTTP GET y la respuesta se recibe en XML. Por ejemplo, una solicitud para obtener la lista de instancias de EC2 tiene la forma https://ec2.amazonaws.com/?Action=DescribeInstances&Version=2016-11-15. La API de S3 sigue un estilo REST y opera sobre los recursos mediante métodos HTTP (GET, PUT, DELETE) y rutas, pero la respuesta es XML.
La maldición de la compatibilidad retroactiva - ¿Por qué no se puede eliminar XML?
Uno de los principios de diseño más importantes de AWS es que "una API, una vez publicada, mantiene por regla general su compatibilidad a largo plazo". La Query API de EC2 ha estado funcionando desde su publicación en 2006, y el formato de respuesta XML no ha cambiado. Dado que las aplicaciones de millones de clientes dependen de esta API, cambiar el formato de respuesta a JSON sería un cambio disruptivo a gran escala. AWS resuelve este problema adoptando JSON en los nuevos servicios mientras mantiene las API de los servicios antiguos tal como están. Los servicios lanzados después de 2012 (DynamoDB, Lambda, API Gateway, etc.) adoptan JSON casi en su totalidad. Sin embargo, no todos los servicios que usan JSON siguen un estilo REST. La API de DynamoDB no es REST con recursos representados en la ruta de la URL, sino un formato JSON-RPC (awsJson1_0 en la nomenclatura de protocolos de Smithy) en el que la operación a invocar se indica en un header contra un único endpoint. El Content-Type es application/x-amz-json-1.0 y la operación que se quiere ejecutar se especifica en el header X-Amz-Target. La API de Lambda sigue un estilo REST con rutas de recursos y métodos HTTP, y el body es JSON. Por otro lado, los servicios iniciales como EC2, S3 y SNS siguen devolviendo respuestas XML. Ahora bien, los servicios iniciales no están fijados a XML para siempre. SQS incorporó la compatibilidad con el protocolo JSON en noviembre de 2023, y para los nuevos usuarios que emplean los AWS SDK más recientes JSON pasó a ser el protocolo predeterminado (las llamadas existentes basadas en XML siguen funcionando igual). Los AWS SDK absorben estas diferencias internamente, por lo que los desarrolladores no necesitan ser conscientes de la distinción entre XML y JSON mientras usen el SDK.
Signature V4 - El mecanismo que firma todas las solicitudes
Otra característica de las API de AWS es que todas las solicitudes requieren una firma criptográfica. El estándar actual, Signature Version 4 (SigV4), concatena el método HTTP, la URL, los headers y el body de la solicitud, los hashea, y genera una firma HMAC-SHA256 con la clave de acceso secreta. Esta firma se incluye en el header Authorization y se verifica del lado de AWS. El proceso de firma de SigV4 consta de 4 pasos. Primero, la creación de la Canonical Request: se normaliza el método HTTP, URI, query string y headers en un formato determinado y se calcula su hash SHA-256. Segundo, la creación del String to Sign: se combina el algoritmo, la fecha, el scope de credenciales y el hash de la canonical request. Tercero, la derivación de la Signing Key: se aplica HMAC-SHA256 en cadena a la fecha, región, servicio y "aws4_request" usando la clave de acceso secreta. Cuarto, el cálculo de la firma: se firma el String to Sign con la Signing Key. Cabe señalar que, como SigV4 es un esquema de clave simétrica que deriva la clave de firma por fecha, región y servicio, la firma generada solo puede verificarse para una única región. Las solicitudes que abarcan varias regiones (como los Multi-Region Access Points de Amazon S3) requieren SigV4a, una extensión con firmas asimétricas basadas en criptografía de curva elíptica, y los AWS SDK y la AWS CLI cambian automáticamente a SigV4a en esas llamadas. SigV4a no deriva claves por fecha ni región: firma con un par de claves derivado de la clave de acceso secreta y el lado de AWS verifica únicamente con la clave pública. Este proceso complejo se ejecuta para cada solicitud de API. Implementarlo manualmente es propenso a errores, lo cual es una de las razones por las que el uso del SDK es prácticamente obligatorio.
La complejidad que los SDK ocultan
Los SDK de AWS son una enorme capa de abstracción que oculta la complejidad de las API a los desarrolladores. Lo que el SDK procesa internamente es muy diverso: firma de solicitudes (SigV4), serialización/deserialización de XML/JSON, lógica de reintentos (con backoff exponencial), manejo de errores (distinción entre errores temporales y permanentes), paginación (obtención automática de grandes cantidades de resultados en múltiples solicitudes), resolución de endpoints regionales, y actualización automática de credenciales temporales (AssumeRole de roles IAM). El SDK v3 (JavaScript) y boto3 (Python) implementan estos procesos como middleware o plugins, permitiendo a los desarrolladores personalizar el comportamiento según sea necesario. Sin embargo, la mayoría de los desarrolladores nunca necesitan tocar estas capas internas. La existencia del SDK significa que la complejidad de las API de AWS no se convierte directamente en complejidad para los desarrolladores. Pero también significa que cuando ocurren problemas (errores de firma, timeouts, throttling), comprender lo que el SDK está haciendo internamente se vuelve importante para la depuración.
La evolución de las API - De Query API a GraphQL y event-driven
El diseño de API de AWS ha evolucionado significativamente desde el lanzamiento de S3 y EC2 en 2006 hasta hoy. Desde la Query API + XML inicial, pasando por REST + JSON, hasta GraphQL con AWS AppSync, cuya disponibilidad general comenzó en 2018, y el enfoque event-driven con EventBridge, los propios paradigmas de API se han diversificado. Lo que se mantiene consistente en el diseño de API de AWS es la postura de que "una API, una vez publicada, mantiene por regla general su compatibilidad a largo plazo". Las nuevas funcionalidades se ofrecen como nuevas versiones de API o parámetros adicionales sin romper las llamadas existentes, y las versiones antiguas pueden seguir usándose tal cual durante mucho tiempo. Este mantenimiento de la compatibilidad retroactiva es la base de la confiabilidad de AWS. Los sistemas que las empresas han construido a lo largo de varios años, en principio, no dejan de funcionar de repente por un cambio en la API. Sin embargo, esto no es una garantía de que una API "nunca se retirará". Como caso real, la API SOAP de S3 dejó de ofrecerse a los nuevos usuarios y llegó a su fin de vida (End of Life) el 31 de agosto de 2025. La compatibilidad a largo plazo es un principio, y existen excepciones con aviso previo y un periodo de migración.
Referencias (recursos oficiales de AWS)
Las fuentes primarias de esta página son el sitio web y la documentación oficiales de AWS. Consulta las páginas oficiales siguientes para conocer las especificaciones y los precios más recientes.
Si esta página y la documentación oficial difieren, prevalece la documentación oficial.