Contents
Introducción
En este artículo se describe con todo detalle cómo consumir APIs externas desde WordPress usando wp_remote_get y cómo cachear las respuestas con transients para optimizar rendimiento, reducir latencia y evitar llegar a límites de cuota de terceros. Encontrarás ejemplos listos para usar, patrones de diseño (incluyendo stale-while-revalidate), manejo de errores, prácticas para multisitio y recomendaciones de seguridad y escalado.
¿Por qué cachear respuestas de APIs externas?
- Rendimiento: reduce el tiempo de respuesta de las páginas al evitar consultas HTTP en cada carga.
- Coste y límites: evita sobrepasar límites de llamadas o generar costes por uso excesivo.
- Resiliencia: permite servir datos antiguos (stale) si la API externa falla temporalmente.
Conceptos clave
- wp_remote_get: función de WP para solicitudes HTTP GET. Retorna array o WP_Error.
- Transients: almacenamiento temporal en la base de datos (o en el object cache si está presente). Se identifican por clave y duración.
- set_transient / get_transient / delete_transient: funciones para manejar transients.
- set_site_transient / get_site_transient: equivalentes para red de sitios (multisite).
Uso básico: ejemplo mínimo con cache
Ejemplo de función simple que solicita una API JSON, valida el resultado y lo guarda en un transient:
10, headers => array( Accept => application/json, User-Agent => MiSite/1.0 ( https://misite.example) ), sslverify => true, ) response = wp_remote_get( url, args ) if ( is_wp_error( response ) ) { // Manejo de error: retornar false o un fallback return false } code = wp_remote_retrieve_response_code( response ) body = wp_remote_retrieve_body( response ) if ( 200 !== intval( code ) empty( body ) ) { return false } // Decodifica JSON data = json_decode( body, true ) if ( null === data ) { return false } // Guarda en transient por 1 hora (3600 segundos) set_transient( transient_key, data, HOUR_IN_SECONDS ) return data } ?>
Explicación rápida
- Se crea una clave a partir de la URL para diferenciar distintas consultas.
- Se intenta get_transient antes de hacer la petición real.
- Se comprueba is_wp_error y el código HTTP para asegurar datos válidos.
- set_transient guarda la respuesta decodificada por 1 hora ajustar según necesidad.
Opciones avanzadas de wp_remote_get
Estos parámetros son útiles en entornos reales:
- timeout: segundos antes de fallar (no pongas valores extremadamente altos).
- headers: autenticación (Bearer), Accept, User-Agent personalizado.
- blocking: false si quieres disparar peticiones no bloqueantes (útil para llamadas asíncronas).
- sslverify: en general debe ser true si trabajas con APIs internas sin certificado válido, ten cuidado.
Ejemplo con header Authorization y timeout corto
8, headers => array( Authorization => Bearer . token, Accept => application/json, ), ) response = wp_remote_get( url, args ) if ( is_wp_error( response ) ) { return false } body = wp_remote_retrieve_body( response ) data = json_decode( body, true ) if ( null === data ) { return false } set_transient( key, data, 30 MINUTE_IN_SECONDS ) // 30 minutos return data } ?>
Patrón stale-while-revalidate (sirve datos viejos mientras se refresca)
Si la API externa es lenta o intermitente, puedes servir datos cacheados incluso cuando han expirado y en segundo plano refrescarlos. Esta técnica mejora disponibilidad.
Cómo implementarlo
- Almacenar junto al dato una marca de tiempo o usar dos transients: uno para el dato y otro para indicar refresh en curso.
- Si el dato caducó, devolver el dato viejo y disparar una tarea de fondo (wp_schedule_single_event) que haga la actualización.
10 ) response = wp_remote_get( url, args ) if ( is_wp_error( response ) ) { return false } body = wp_remote_retrieve_body( response ) data = json_decode( body, true ) if ( null === data ) { return false } // Guardamos por 1 hora set_transient( key_data, data, HOUR_IN_SECONDS ) return data } ?>
Invalidación del cache: cuándo y cómo
Limpiar transients oportunamente es clave. Ejemplos comunes:
- Eliminar transients relacionados cuando se actualiza contenido que afecta los datos (hook save_post, update_option, etc.).
- Permitir parámetros de cache-bust en la URL para forzar refresco manual (ej. ?refresh_api=1).
- Proveer un endpoint admin o un WP-CLI command para purgar caches.
Ejemplo: borrar cache al guardar un post
Multisitio: set_site_transient
En instalaciones WordPress Multisite usa set_site_transient / get_site_transient si quieres compartir cache entre sitios de la red.
Consideraciones sobre object cache persistente (Redis / Memcached)
- Si el sitio tiene un object cache persistente, los transients se guardan en ese sistema en lugar de las opciones. Esto es más rápido y reduce carga en la BD.
- Si usas Redis/Memcached, asegúrate de que el tamaño de los valores sea razonable y que el TTL de los transients sea gestionado según la política de expiración del cache.
- Para datos muy grandes o muy frecuentemente actualizados, considera almacenamiento especializado (tables personalizadas, cache en filesystem o un CDN).
Buenas prácticas y recomendaciones
- Prefijos de claves: usa prefijos únicos para evitar colisiones (ej. miplugin_api_).
- Hash de URLs: cuando la URL es larga o contiene query params, usa md5 o sha1 para generar la clave.
- Duración razonable: no uses expiraciones demasiado cortas si la API cambia poco tampoco uses TTL demasiado largos si los datos requieren frescura.
- Manejo de errores: siempre comprueba is_wp_error y códigos HTTP. Considera retornar datos stale si falla la API.
- Seguridad: nunca expongas tokens en front-end. Si es necesario hacer llamadas desde cliente, crea endpoints en PHP que proxyen y apliquen cache y validación.
- Evita bloqueos en requests de usuario: usa stale-while-revalidate o jobs en background para evitar latencias largas en la carga de la página.
- Monitoreo: registra errores de llamadas externas y latencias para detectar degradaciones de la API tercera.
Comparativa rápida
Tipo | Uso | Persistencia | Casos recomendados |
---|---|---|---|
Transient (set_transient) | Cache temporal por clave | Opcional (DB) o persistente si existe object cache | Respuestas de APIs por periodo limitado |
Site Transient (set_site_transient) | Cache compartido en Multisite | Igual que transients | Datos que deben ser comunes a toda la red |
Object Cache persistente | Caché en Redis/Memcached | Persistente en memoria (según configuración) | Alto rendimiento y reducción de llamadas a BD |
Errores comunes y cómo evitarlos
- No comprobar is_wp_error: puede provocar warnings o comportamiento inesperado.
- Claves de transient muy largas: acorta con md5 para evitar problemas con nombres en la base de datos.
- Usar timeouts grandes: hace que la experiencia del usuario sea mala es mejor usar cache y refresco en background.
- Confiar en transients sin plan de invalidación: los datos pueden quedarse obsoletos indefinidamente. Diseña una estrategia de expiración o invalidación manual.
Ejemplo completo: shortcode público que muestra datos cacheados
Shortcode que muestra una lista de items desde una API externa, usando cache y manejo básico de errores.
, cache => 3600, ), atts ) if ( empty( atts[url] ) ) { returnURL no definida
} url = esc_url_raw( atts[url] ) cache_seconds = intval( atts[cache] ) key = short_api_ . md5( url ) data = get_transient( key ) if ( false === data ) { response = wp_remote_get( url, array( timeout => 8 ) ) if ( is_wp_error( response ) ) { returnError al conectar con la API
} body = wp_remote_retrieve_body( response ) data = json_decode( body, true ) if ( null === data ) { returnRespuesta inválida
} set_transient( key, data, cache_seconds ) } if ( empty( data ) ! is_array( data ) ) { returnNo hay datos
} output =
-
foreach ( data as item ) {
title = isset( item[title] ) ? esc_html( item[title] ) : esc_html( wp_json_encode( item ) )
output .=
- . title . } output .=
Resumen de reglas prácticas
- Usa get_transient antes de llamar a wp_remote_get.
- Valida respuesta (is_wp_error, código HTTP, json_decode correctamente).
- Usa claves con prefijo y hash si la URL incluye parámetros largos.
- Implementa stale-while-revalidate o tareas en background para no bloquear al usuario.
- Elimina transients cuando el contenido que influye en la API cambie.
- Considera object cache persistente (Redis/Memcached) para alta escala.
Fin del tutorial
Implementando estas prácticas obtendrás integraciones con APIs externas más rápidas, robustas y escalables dentro de WordPress usando wp_remote_get y transients. Ajusta tiempos de expiración, manejo de errores y estrategias de invalidación según las características de la API externa y los requisitos de tu proyecto.
|
Acepto donaciones de BAT's mediante el navegador Brave 🙂 |