0Pricing
DevOps Bootcamp · Lección

Consumo conjunto de API REST con curl y jq

Encadene solicitudes de curl con jq para extraer, paginar y reformatear respuestas de API en tiempo real desde scripts.

Consumo conjunto de API REST con curl y jq es una lección gratuita de DevOps Bootcamp en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de DevOps Bootcamp, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de DevOps Bootcamp incluye 4 lecciones en total.

Por qué curl + jq forman una combinación tan potente

Las API REST devuelven JSON. curl obtiene la respuesta sin procesar; jq la recorta, filtra y remodela, todo en una sola canalización. No necesita un script de Python, Postman ni un archivo intermedio.

  • curl gestiona HTTP: métodos, encabezados, autenticación y redirecciones.
  • jq gestiona JSON: filtrado, mapeo, transformación y formato.
  • Conectarlos mediante una tubería crea flujos de trabajo de API concisos y componibles.

Esta lección desarrolla esa habilidad desde los fundamentos, incluyendo patrones reales de paginación y scripting.

Canalización básica de curl a jq

El patrón más sencillo consiste en enviar directamente la salida de curl a jq. Use -s (silencioso) para ocultar el indicador de progreso de curl y hacer que solo el cuerpo JSON llegue a jq.

  • -s — modo silencioso, sin barra de progreso.
  • . — filtro de identidad de jq; muestra con formato legible la respuesta completa.
  • -r en jq — salida sin formato (sin comillas alrededor de las cadenas).
#!/usr/bin/env bash
# Fetch a public endpoint and pretty-print the JSON
curl -s 'https://jsonplaceholder.typicode.com/todos/1' | jq '.'

# Extract just the title field as a plain string
curl -s 'https://jsonplaceholder.typicode.com/todos/1' | jq -r '.title'

Configurar encabezados de solicitud y pasar tokens de autenticación

La mayoría de las API de producción requieren un encabezado Authorization o una clave de API. Pase los encabezados con -H y almacene los secretos en variables de entorno; nunca los incluya directamente en el código.

  • -H 'Authorization: Bearer $TOKEN' — inyecta el encabezado de autenticación.
  • -H 'Accept: application/json' — solicita explícitamente una respuesta JSON.
  • Las variables se expanden dentro de comillas dobles; use " alrededor de la cadena del encabezado.
#!/usr/bin/env bash
TOKEN="${GITHUB_TOKEN}"   # set in your shell environment
USER="octocat"

curl -s \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Accept: application/vnd.github+json" \
  "https://api.github.com/users/${USER}" \
| jq '{login: .login, repos: .public_repos, followers: .followers}'

Filtrar arrays: .[] y select()

Las API suelen devolver arrays. Use .[] para iterar sobre cada elemento y, después, select() para conservar únicamente los elementos que cumplan una condición.

  • .[] — descompone un array en un flujo de objetos.
  • select(.field == value) — conserva únicamente los objetos que coinciden.
  • Encadene varios filtros con |.
#!/usr/bin/env bash
# Fetch all todos and keep only the completed ones
curl -s 'https://jsonplaceholder.typicode.com/todos' \
| jq '[.[] | select(.completed == true) | {id, title}]'

# Count how many are completed
curl -s 'https://jsonplaceholder.typicode.com/todos' \
| jq '[.[] | select(.completed == true)] | length'

Extraer varios campos con map()

map() aplica una transformación a cada elemento de un array y devuelve un array nuevo — equivalente a [.[] | ...], pero más legible.

  • map({key: .field}) — cambia la estructura de cada objeto.
  • Combínelo con @csv o @tsv para generar una salida tabular.
  • Use -r con @csv/@tsv para obtener texto sin formato (sin las comillas de JSON).
#!/usr/bin/env bash
# Reshape a posts list into id + title pairs
curl -s 'https://jsonplaceholder.typicode.com/posts' \
| jq 'map({id, title: .title[0:40]})'

# Output as CSV for import into a spreadsheet
curl -s 'https://jsonplaceholder.typicode.com/posts' \
| jq -r '.[] | [.id, .userId, .title] | @csv'

Patrón de paginación — repetir hasta obtener una página vacía

La mayoría de las API pagina los resultados. Un patrón habitual consiste en usar un bucle while que incrementa un contador de páginas y se detiene cuando el array devuelto está vacío.

  • Guarde la respuesta de curl en una variable con $(curl ...).
  • Use jq 'length' para comprobar si la página contiene elementos.
  • Acumule los resultados con jq -s (slurp) o añádalos a un archivo.
#!/usr/bin/env bash
# Paginate through jsonplaceholder posts (simulated: page stops at page 2
# because the API returns the full list regardless of ?_page, but the
# pattern is correct for real paginated APIs)

PAGE=1
PER_PAGE=10
OUTPUT="all_posts.json"
echo '[]' > "$OUTPUT"

while true; do
  RESPONSE=$(curl -s "https://jsonplaceholder.typicode.com/posts?_page=${PAGE}&_limit=${PER_PAGE}")
  COUNT=$(echo "$RESPONSE" | jq 'length')

  if [ "$COUNT" -eq 0 ]; then
    echo "No more pages. Stopping at page $((PAGE - 1))."
    break
  fi

  # Merge new items into the accumulated JSON array
  CURRENT=$(cat "$OUTPUT")
  echo "$CURRENT" "$RESPONSE" | jq -s '.[0] + .[1]' > "$OUTPUT"
  echo "Page $PAGE: fetched $COUNT items."
  PAGE=$((PAGE + 1))
done

echo "Total collected: $(jq 'length' "$OUTPUT")"

Paginación mediante el encabezado Link (estilo GitHub)

GitHub y muchas otras API utilizan un encabezado de respuesta Link para proporcionar la URL de la página siguiente. Debe analizar el encabezado en lugar de intentar adivinar la URL.

  • curl -i incluye los encabezados de respuesta en stdout; también puede usar -D - para volcar los encabezados en stdout.
  • Analice el encabezado Link: <url>; rel="next" con grep y sed.
  • Repita el bucle hasta que no haya ningún enlace rel="next".
#!/usr/bin/env bash
# Follow Link-header pagination (GitHub repos example)
# Requires GITHUB_TOKEN in environment
TOKEN="${GITHUB_TOKEN}"
NEXT_URL="https://api.github.com/users/torvalds/repos?per_page=5"
ALL_REPOS="[]"

while [ -n "$NEXT_URL" ]; do
  # Capture full response (headers + body) to a temp file
  TMPFILE=$(mktemp)
  curl -sD "$TMPFILE" \
    -H "Authorization: Bearer ${TOKEN}" \
    -H "Accept: application/vnd.github+json" \
    "$NEXT_URL" \
  | {
      BODY=$(cat)
      ALL_REPOS=$(echo "$ALL_REPOS" "$BODY" | jq -s '.[0] + .[1]')
      echo "$ALL_REPOS" > /tmp/repos_acc.json
    }

  # Extract next URL from Link header
  NEXT_URL=$(grep -i '^link:' "$TMPFILE" \
    | sed -E 's/.*<([^>]+)>; rel="next".*/\1/;t;d')
  rm -f "$TMPFILE"
done

echo "Total repos: $(jq 'length' /tmp/repos_acc.json)"

Encadenar solicitudes — usar la salida de una llamada como entrada de otra

Un flujo de trabajo habitual consiste en obtener una lista, extraer un ID y, después, obtener los detalles correspondientes a cada ID. Almacene los valores intermedios mediante la sustitución de comandos $() y páselos a la URL siguiente.

  • Extraiga un único valor con jq -r '.field'.
  • Recorra varios ID con jq -r '.[].id' dentro de un bucle while read.
  • Use sleep entre solicitudes para respetar los límites de frecuencia.
#!/usr/bin/env bash
# Step 1: get all user IDs from the /users endpoint
# Step 2: for each user, fetch their posts and count them

curl -s 'https://jsonplaceholder.typicode.com/users' \
| jq -r '.[].id' \
| while read -r USER_ID; do
    POST_COUNT=$(curl -s "https://jsonplaceholder.typicode.com/posts?userId=${USER_ID}" \
                 | jq 'length')
    echo "User ${USER_ID}: ${POST_COUNT} posts"
    sleep 0.1   # be polite to the API
done

Solicitudes POST — enviar cargas JSON

Para crear o actualizar recursos, envíe una solicitud POST o PUT con un cuerpo JSON. Use -X POST, -H 'Content-Type: application/json' y -d para el cuerpo. Cree la carga útil con jq -n para evitar problemas con las comillas.

  • jq -n --arg key value '{key: $key}' — interpolación segura de variables en jq.
  • Dirija el JSON construido directamente a -d @- de curl (lee el cuerpo desde stdin).
  • Analice la respuesta inmediatamente con otro filtro de jq.
#!/usr/bin/env bash
TITLE="My New Post"
BODY_TEXT="Written via curl and jq."
USER_ID=1

# Build the JSON payload safely and POST it
RESPONSE=$(jq -n \
  --arg title   "$TITLE" \
  --arg body    "$BODY_TEXT" \
  --argjson userId "$USER_ID" \
  '{title: $title, body: $body, userId: $userId}' \
| curl -s \
    -X POST \
    -H 'Content-Type: application/json' \
    -d @- \
    'https://jsonplaceholder.typicode.com/posts')

echo "Created post ID: $(echo "$RESPONSE" | jq '.id')"
echo "Full response:"
echo "$RESPONSE" | jq '.'

Gestión de errores — códigos de estado HTTP y errores de API

Una conexión HTTP correcta no significa que la llamada a la API haya sido correcta. Compruebe por separado el código de estado HTTP y el campo de error JSON.

  • curl -w '%{http_code}' añade el código de estado a stdout; use -o para escribir el cuerpo en un archivo.
  • Compare el código en el script y gestione los errores 4xx y 5xx de forma diferente.
  • Muchas API incluyen {"error": "..."} en el cuerpo; compruébelo con has() o type de jq.
#!/usr/bin/env bash
API_URL='https://jsonplaceholder.typicode.com/todos/99999'
TMPBODY=$(mktemp)

HTTP_CODE=$(curl -s -o "$TMPBODY" -w '%{http_code}' "$API_URL")

if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then
  echo "Success ($HTTP_CODE):"
  jq '.' "$TMPBODY"
elif [ "$HTTP_CODE" -eq 404 ]; then
  echo "Resource not found (404). Body:"
  jq '.' "$TMPBODY"
elif [ "$HTTP_CODE" -ge 500 ]; then
  echo "Server error ($HTTP_CODE). Retrying later."
else
  echo "Unexpected status: $HTTP_CODE"
  cat "$TMPBODY"
fi

rm -f "$TMPBODY"

Crear una función auxiliar reutilizable para API

Envuelva en una función de shell el código repetitivo de curl y comprobación de errores. La función gestiona la autenticación, la comprobación del estado y la extracción de JSON; quienes la llamen solo tienen que pasar el endpoint y un filtro de jq.

  • Devuelva códigos de salida distintos de cero en caso de errores HTTP para que quienes llamen a la función puedan usar || o set -e.
  • Acepte un argumento de filtro de jq para que la misma función sirva para muchos endpoints.
  • Cargue este archivo de funciones desde cualquier script que necesite acceder a la API.
#!/usr/bin/env bash
# api_get <endpoint_path> <jq_filter>
# Returns filtered JSON or exits non-zero on error.
api_get() {
  local PATH_PART="$1"
  local JQ_FILTER="${2:-.}"
  local BASE_URL='https://jsonplaceholder.typicode.com'
  local TMPBODY
  TMPBODY=$(mktemp)

  local HTTP_CODE
  HTTP_CODE=$(curl -s \
    -o "$TMPBODY" \
    -w '%{http_code}' \
    "${BASE_URL}${PATH_PART}")

  if [ "$HTTP_CODE" -lt 200 ] || [ "$HTTP_CODE" -ge 300 ]; then
    echo "[ERROR] HTTP $HTTP_CODE for ${PATH_PART}" >&2
    rm -f "$TMPBODY"
    return 1
  fi

  jq -r "$JQ_FILTER" "$TMPBODY"
  rm -f "$TMPBODY"
}

# Usage examples
api_get '/todos/1' '.title'
api_get '/posts?userId=1' '[.[] | .title]'
api_get '/users' '.[] | "\(.id) \(.name) <\(.email)>"'

Comprobación de conocimientos: estrategia de paginación

Compruebe que entiende cómo gestionar respuestas paginadas de una API REST en un script de Bash mediante curl y jq.

Resumen de la lección: scripting de API con curl + jq

Ahora dispone de un conjunto completo de herramientas para consumir API REST desde la línea de comandos de Bash:

  • Pipeline básico: curl -s URL | jq 'filter' — la base de todo.
  • Encabezados de autenticación: pase los tokens mediante -H desde variables de entorno; nunca los escriba directamente en el código.
  • Gestión de arrays: .[], select() y map() permiten filtrar y cambiar la estructura de las respuestas de la API.
  • Paginación: use un bucle con un contador de páginas (un array vacío como indicador de finalización) o analice los encabezados Link en las API que proporcionan la URL siguiente.
  • Encadenamiento: extraiga los ID de una respuesta y páselos a la siguiente solicitud dentro de un bucle while read.
  • POST con cargas seguras: cree cuerpos JSON mediante jq -n --arg y diríjalos a -d @- de curl.
  • Gestión de errores: separe el estado HTTP (-w '%{http_code}') de los errores de nivel de API incluidos en el cuerpo.
  • Función auxiliar reutilizable: encapsule el código repetitivo en una función de shell para mantener los scripts concisos y DRY.

Combine estos patrones y podrá automatizar cualquier flujo de trabajo con una API JSON completamente desde el shell, sin necesidad de ningún runtime adicional.

Preguntas frecuentes

¿La lección «Consumo conjunto de API REST con curl y jq» es gratis?

Sí — el texto completo de «Consumo conjunto de API REST con curl y jq» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de DevOps Bootcamp, actualiza a CoddyKit PRO. El curso de DevOps Bootcamp incluye 4 lecciones en total.

¿Qué aprenderé en «Consumo conjunto de API REST con curl y jq»?

Encadene solicitudes de curl con jq para extraer, paginar y reformatear respuestas de API en tiempo real desde scripts. Practicas DevOps Bootcamp con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar DevOps Bootcamp?

No se requiere experiencia previa. DevOps Bootcamp en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.

¿Cuánto tiempo toma la lección «Consumo conjunto de API REST con curl y jq»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de DevOps Bootcamp?

Sí. Cada lección de DevOps Bootcamp incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Filtrado y selección de JSON con pipelines de jq
  2. Transformación y construcción de objetos JSON con jq
  3. Consumo conjunto de API REST con curl y jq
  4. Edición de archivos de configuración YAML con yq
← Volver a DevOps Bootcamp