1. Blog
  2. api

Peticiones HTTP 101: Una guía completa para entenderlas

Escrito por 5 min read #api

Las APIs desempeñan un papel fundamental en la vida cotidiana de los desarrolladores al proporcionar una vía eficiente y versátil para acceder y manipular datos en servidores web.

En este artículo, profundizaremos en el concepto de las peticiones HTTP, explorando sus componentes y su ejecución en diversos entornos de programación. Además, examinaremos detalladamente cómo estas solicitudes son transmitidas a través de una red, respaldando nuestros análisis con ejemplos claros y concisos.

¿Qué es una petición HTTP?

Una petición HTTP, también conocida como llamada HTTP, constituye la solicitud que un cliente, como un navegador web, envía a un servidor. Esta solicitud está compuesta por diversos elementos y debe seguir un formato estándar para que el servidor pueda interpretarla adecuadamente.

El formato de una solicitud HTTP, denominado mensaje HTTP, se describe extensamente en los documentos RFC (Request for Comments en inglés), en este caso el RFC 7230. Estos documentos detallan las especificaciones técnicas, estándares y protocolos relacionados con las comunicaciones HTTP.

Los mensajes HTTP se componen de tres elementos principales: la línea de solicitud, las cabeceras y el cuerpo. Estos componentes trabajan en conjunto para formar una solicitud completa y comprensible para el servidor, permitiendo a los clientes solicitar, crear, modificar o eliminar información de manera eficiente.

Componentes de una petición HTTP

Línea de solicitud

La primera línea del mensaje, que incluye:

  • Método. La acción que queremos ejecutar. Por ejemplo GET es usado habitualmente para solicitar datos y POST para enviarlos.
  • URI. El path o la ubicación del recurso. Por ejemplo /users.
  • Versión. La versión del protocolo HTTP que vamos a usar. Por ejemplo, HTTP/1.1 o HTTP/2.

Estas tres parte, unidas, van a conformar la línea completa:

POST /post HTTP/1.1

Cabeceras

Las cabeceras son líneas de información adicional o metadatos enviados junto con la solicitud. Algunas cabeceras muy comunes (aunque hay muchas otras) son:

  • Host. La única requerida y la más importante. Indica el nombre del servidor.
  • Accept. Indica los tipos de formato que el cliente es capaz de entender en la respuesta, como HTML, JSON o XML.
  • Content-Type. Indica el formato de los datos que se van a enviar en el cuerpo (en el siguiente epígrafe explicaremos lo que es el cuerpo). Esta cabecera sólo tiene sentido en las peticiones que envían datos, como POST, PUT o PATCH.
  • User-Agent. Normalmente indica el nombre y versión del cliente que se está usando, como por ejemplo: curl/8.5.0.

Para ilustrar estos conceptos, consideremos un ejemplo práctico de una solicitud HTTP con sus respectivas cabeceras:

Host: httpbin.org
Accept: application/json
Content-Type: application/json
User-Agent: curl/8.5.0

Este conjunto de cabeceras informa al servidor httpbin.org de que se está utilizando cURL en la versión 8.5.0, y que se acepta una respuesta en formato JSON.

Cuerpo

Finalmente, el cuerpo de la petición se incluye únicamente en aquellos mensajes HTTP que desean enviar datos adicionales al servidor. Como mencionamos anteriormente, este componente se agrega en solicitudes que utilizan los métodos POST, PUT o PATCH, permitiendo la transferencia de información adicional junto con la solicitud.

Ten en cuenta de que para definir el formato de los datos que envías, es necesario utilizar la cabecera Content-Type. Esta directiva le indica al servidor cómo debe interpretar la información en el cuerpo. Por ejemplo, si estás enviando datos en formato JSON, la cabecera Content-Type debería ser application/json; mientras que si estás enviando un formulario HTML, debes utilizar application/x-www-form-urlencoded.

Un ejemplo de cuerpo podría ser este:

{
  "hello": "world"
}

Resumen

Uniendo los ejemplos expuestos anteriormente, vamos a executar una petición y a crear un mensaje HTTP real.

Para ello, usaremos cURL, un conocido cliente que permite hacer llamadas HTTP desde el terminal.

curl -X POST 'https://httpbin.org/post' \
  --header "Accept: application/json" \
  --header "Content-Type: application/json" \
  --data '{ "hello": "world" }'

Este comando cURL está enviando una solicitud POST al path /post en el servidor httpbin.org, indicando que acepta respuestas en formato JSON y que está enviando datos en formato JSON.

El mensaje HTTP generado para el comando anterior sería algo así:

POST /post HTTP/1.1
Host: httpbin.org
Accept: application/json
Content-Type: application/json

{ "hello": "world" }

¿Cómo se transmite una petición HTTP?

Una vez que hemos formateado nuestro mensaje HTTP, ¿cómo lo transmitimos al servidor? A través de un socket TCP. Este proceso es esencial para entender cómo la información es enviada y recibida entre el cliente y el servidor en una red.

Por ejemplo, en Ruby, podemos ejecutar esto mediante el uso de sockets TCP:

require 'socket'

# Crear un socket TCP
client_socket = TCPSocket.new('httpbin.org', 443) # Puerto 443 para HTTPS

# Definir la solicitud HTTP
http_request = <<~HTTP_REQUEST
  POST /post HTTP/1.1
  Host: httpbin.org
  Accept: application/json
  Content-Type: application/json

  { "hello": "world" }
HTTP_REQUEST

# Enviar la solicitud al servidor
client_socket.puts http_request

# Manejar la respuesta del servidor
response = client_socket.read
puts "Respuesta del servidor:"
puts response

# Cerrar la conexión
client_socket.close

Simplificación con librerías

Generar mensajes HTTP y escribir código repetitivo cada vez que queremos hacer una solicitud a una API puede ser un proceso tedioso. Afortunadamente, existen bibliotecas que simplifican este proceso, tanto las integradas en los lenguajes como las externas que se pueden instalar.

Estas bibliotecas automatizan los detalles de bajo nivel y proporcionan una interfaz más intuitiva para interactuar con servicios web, agilizando así el desarrollo de aplicaciones que dependen de comunicaciones HTTP.

¿Cómo se hace una petición HTTP?

Vamos a reescribir nuestro ejemplo anterior en Ruby que utilizaba sockets a otros en diferentes lenguajes.

Javascript

const url = 'https://httpbin.org/post';
const headers = {
  'Accept': 'application/json',
  'Content-Type': 'application/json',
};
const data = { 'hello': 'world' };

fetch(url, {
  method: 'POST',
  headers: headers,
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(data => {
    console.log(data);
  });

Python

import requests

url = 'https://httpbin.org/post'
headers = {
  'Accept': 'application/json',
  'Content-Type': 'application/json',
}
data = {'hello': 'world'}

response = requests.post(url, json=data, headers=headers)

print(response.json())

PHP

$url = 'https://httpbin.org/post';
$headers = [
  'Accept: application/json',
  'Content-Type: application/json',
];
$data = [
  'hello' => 'world',
];

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$response = curl_exec($ch);

echo $response;

curl_close($ch);

Ruby

require 'net/http'
require 'json'

url = URI.parse('https://httpbin.org/post')
headers = {
  'Accept' => 'application/json',
  'Content-Type' => 'application/json',
}
data = { 'hello' => 'world' }

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = (url.scheme == 'https')

request = Net::HTTP::Post.new(url.path, headers)
request.body = data.to_json

response = http.request(request)

puts JSON.parse(response.body)

Resumen

En este artículo hemos analizado proceso de creación de las peticiones HTTP, explorando cada una de sus partes y explicando la estructura fundamental de este protocolo. También nos sumergimos en el concepto del mensaje HTTP, desglosando sus elementos.

Además, hemos explicado cómo se envían las peticiones internamente a través de sockets TCP. Esta parte del proceso es fundamental para comprender cómo la información es enviada y recibida entre el cliente y el servidor en un entorno de red.

Para proporcionar una comprensión más completa, hemos incluido varios ejemplos prácticos en diferentes lenguajes, lo que permite visualizar cómo se implementan en la práctica.

En resumen, las peticiones HTTP son la columna vertebral de la comunicación en la web moderna, y comprender su funcionamiento es fundamental para cualquier desarrollador. Con este conocimiento y el apoyo de las herramientas adecuadas, podemos construir aplicaciones web robustas y eficientes que satisfagan las necesidades de nuestros usuarios.

Simplifica la integración de tu API

Convierte usuarios confundidos en clientes felices facilitándoles el proceso de onboarding

Hello API – Product screenshot