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 Linux Command Line & Bash Scripting Mastery 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 Linux Command Line & Bash Scripting Mastery, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Linux Command Line & Bash Scripting Mastery 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.-ren 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
@csvo@tsvpara generar una salida tabular. - Use
-rcon@csv/@tsvpara 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 -iincluye los encabezados de respuesta en stdout; también puede usar-D -para volcar los encabezados en stdout.- Analice el encabezado
Link: <url>; rel="next"congrepysed. - 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 buclewhile read. - Use
sleepentre 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
doneSolicitudes 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-opara 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 conhas()otypede 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
||oset -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
-Hdesde variables de entorno; nunca los escriba directamente en el código. - Gestión de arrays:
.[],select()ymap()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
Linken 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 --argy 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 Linux Command Line & Bash Scripting Mastery, actualiza a CoddyKit PRO. El curso de Linux Command Line & Bash Scripting Mastery 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 Linux Command Line & Bash Scripting Mastery 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 Linux Command Line & Bash Scripting Mastery?
No se requiere experiencia previa. Linux Command Line & Bash Scripting Mastery 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 Linux Command Line & Bash Scripting Mastery?
Sí. Cada lección de Linux Command Line & Bash Scripting Mastery 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
- Filtrado y selección de JSON con pipelines de jq
- Transformación y construcción de objetos JSON con jq
- Consumo conjunto de API REST con curl y jq
- Edición de archivos de configuración YAML con yq