El HTTP API de WordPress consiste en un montón de funciones que te ayudarán a hacer llamadas HTTP mucho más fácilmente. No hay necesidad de jugar con file_get_contents o cURL nunca más, solo una única interfaz unificada. Esto es impresionante para interactuar con las API de terceros, especialmente las llenas de REST como Twitter, Facebook, MailChimp, y otros.

Los Fundamentos de HTTP

Todos hemos visto el HTTP en acción antes. De hecho, si esta es tu primera vez en la web y es la primera cosa que está leyendo, ya has visto a HTTP haciendo su magia. HTTP es un protocolo de red usado para entregar todos los archivos y datos (recursos) a través de las Interwebs.

Básicamente la ecuación tiene dos partes: la solicitud HTTP y la respuesta HTTP, o transacción. Tanto la petición como la respuesta tienen una estructura muy similar, ambas tienen cuatro partes:

  • Una línea inicial
  • Cero o más líneas de cabecera
  • Una línea en blanco
  • Un cuerpo del mensaje opcional

La Línea Inicial

Las solicitudes utilizan la línea inicial para enviar tres informaciones: el nombre del método, la ruta y la versión HTTP. Por ejemplo, al ver la página principal del blog de Kinsta, se vería esto en la línea inicial de la solicitud.

GET /blog/ HTTP/1.1

Las respuestas también proporcionan tres piezas de información, aunque algo diferentes: La versión HTTP, el código de la respuesta y una descripción de la respuesta. Al hacer una solicitud al blog principal de Kinsta enviará una respuesta HTTP con la siguiente línea inicial:

HTTP/1.0 200 OK

Cabeceras

Las cabeceras contienen varios bits de información sobre la solicitud o la respuesta. HTTP 1.1 define 46 tipos de cabeceras, pero solo uno es necesario (solo para las peticiones), la cabecera «Host». Echa un vistazo a la captura de pantalla de las herramientas de desarrollo de mi Chrome que muestra algunas de las cabeceras enviadas junto con una solicitud al blog principal de Kinsta:

HTTP request headers sent

Cuerpo

El cuerpo suele contener datos sobre el recurso solicitado. Si envías una solicitud GET al blog principal de Kinsta, deberías recibir el HTML necesario para mostrar la página (el recurso) en el contenido del cuerpo.

.

Más Información

Es todo lo que necesitas saber ahora mismo sobre el HTTP. Nos centraremos principalmente en el nombre del método (GET, POST, etc.), las cabeceras y el cuerpo. Si quieres saber más, te recomiendo la explicación de James Marshall sobre el HTTP, es un manual muy bien escrito para satisfacer tus necesidades sobre el HTTP.

Acerca del REST API

La Rest API, o la metodología REST tiene como objetivo proporcionar una forma simple y estándar de interactuar con una aplicación (aquí puedes aprender más sobre los fundamentos de la REST API de WordPress). A menudo se utiliza junto con HTTP para crear un sistema de interacciones muy comprensible. Se basa en rutas y verbos HTTP.

Los verbos HTTP son los mismos que los nombres de los métodos que vimos anteriormente, los más comunes son: GET, POST, PUT, DELETE. Creo que PUT es el único ambiguo aquí, piensa en ello como un comando de actualización. Al usar estos verbos junto con las rutas podemos construir un sistema significativo:

GET /post/1/ se utilizaría para recuperar el post con el ID 1. DELETE /post/1/  para borrar el mismo post. También podríamos usar PUT /post/1/ para actualizarlo, suministrando la información pertinente en el cuerpo y las cabeceras de la solicitud.

Estoy seguro de que puedes ver que con solo añadir una versión HTTP a nuestros códigos de arriba, tenemos la línea inicial de una transacción HTTP, que es solo una de las razones por las que este sistema es tan poderoso.

Usando el  HTTP API de WordPress

Armados con todo ese conocimiento podemos comprender fácilmente cómo funciona el HTTP API de WordPress. Los cuatro métodos utilizados para hacer peticiones e interceptar las respuestas son:

  • wp_remote_get()
  • wp_remote_post()
  • wp_remote_head()
  • wp_remote_request()

Las dos primeras funciones se explican por sí solas, utilizan los métodos GET y POST respectivamente en la solicitud. La tercera función utiliza el método HEAD, algo de lo que aún no hemos hablado. Este método se utiliza para recuperar solo las cabeceras de una respuesta. Esto puede ahorrar muchos gastos generales si solo necesitamos algunos metadatos sobre un recurso. La función final es genérica, se puede especificar qué método se desea utilizar dentro de los parámetros de la función.

Hay cinco funciones adicionales que podemos utilizar para recuperar partes específicas de la respuesta. Estas son básicamente atajos para navegar por la masa de datos que recibimos:

  • wp_remote_retrieve_body()
  • wp_remote_retrieve_header()
  • wp_remote_retrieve_headers()
  • wp_remote_retrieve_response_code()
  • wp_remote_retrieve_response_message()

Nuestra Primera Solicitud de HTTP

Hagamos una prueba rápida recuperando la información de la cabecera del blog de Kinsta. Puedes hacer esto en cualquier lugar dentro de un plugin o un tema, pero obviamente debes estar dentro de un entorno de prueba para asegurarte de no emitir texto no deseado en un sitio en vivo.

$response = wp_remote_head( 'https://kinsta.com/blog/' );
var_dump( $response )

Como puedes ver en la respuesta que obtenemos a continuación, la sección del cuerpo está vacía (ya que estamos usando el método HEAD) y se muestran todos las cabeceras. Para seleccionar solo las cabeceras sin todos los demás miembros del array podríamos usar la función wp_remote_retrieve_headers().

array (size=5)
  'headers' => 
    array (size=13)
      'server' => string 'nginx' (length=5)
      'date' => string 'Wed, 22 Jul 2015 14:22:07 GMT' (length=29)
      'content-type' => string 'text/html; charset=UTF-8' (length=24)
      'connection' => string 'close' (length=5)
      'vary' => string 'Accept-Encoding' (length=15)
      'x-pingback' => string 'https://kinsta.com/xmlrpc.php' (length=29)
      'x-powered-by' => string 'HHVM/3.8.0' (length=10)
      'link' => string '; rel="https://github.com/WP-API/WP-API"' (length=68)
      'x-frame-options' => string 'DENY' (length=4)
      'x-content-type-options' => string 'nosniff' (length=7)
      'strict-transport-security' => string 'max-age=31536000' (length=16)
      'x-kinsta-cache' => string 'HIT' (length=3)
      'content-encoding' => string 'gzip' (length=4)
  'body' => string '' (length=0)
  'response' => 
    array (size=2)
      'code' => int 200
      'message' => string 'OK' (length=2)
  'cookies' => 
    array (size=0)
      empty
  'filename' => null

Entendiendo a Las API

twitter wordpress api

La mayor barrera que veo para los desarrolladores es la gran cantidad de cosas nuevas que necesitan poner en marcha para hacer que una llamada a la API funcione. Necesitas saber sobre HTTP, cómo hacer peticiones y también cómo autenticar correctamente, sin eso, cada llamada fallará. Veamos un ejemplo a través de la API de Twitter, ya que tienen una gran documentación.

Estaremos viendo la autenticación de solo aplicación (que es un flujo más fácil), seguiré los mismos pasos que Twitter sugiere. Antes de empezar, asegúrate de crear una aplicación de Twitter.

Deberías poder añadir el código que aparece a continuación en cualquier lugar dentro de un tema o un plugin, pero como mencionamos antes, ¡asegúrate de usar un sitio de prueba!

Paso 1: Codifica la Clave y Código Secreto del consumidor

Una vez que hayas creado una aplicación, debes tener a mano una llave de consumidor y un código secreto. Para hacer las cosas más fáciles, vamos a crear constantes que mantengan esta información para nosotros.

define( 'TWITTER_CONSUMER_KEY', '12disnir382jeqwdasd23wdasi' );
define( 'TWITTER_CONSUMER_SECRET', '23wdajskduhtrq2c32cuq9r8uhuf' )

Los tres pasos para crear una versión codificada de estos se establecen en los documentos:

  • La URL codifica la clave del consumidor y el código secreto del consumidor
  • Concentrarlas con un colon
  • Base64 codifica toda la cadena

En PHP esto será bastante fácil de hacer, ¡aquí lo tienes!


$key = urlencode( TWITTER_CONSUMER_KEY );
$secret = urlencode( TWITTER_CONSUMER_SECRET );
$concatenated = $key . ':' . $secret;
$encoded = base64_encode( $concatenated );

Paso 2: Obtén un Token de Bearer

En lugar de utilizar tu contraseña real, envías a Twitter tu cadena codificada (que utiliza tus credenciales de la API) y recibes un pase temporal que es válido por un tiempo determinado. Para hacer esto haremos una solicitud HTTP, esto es lo que Twitter tiene que decir:

  • La petición debe ser una petición HTTP POST.
  • La solicitud debe incluir una cabecera de autorización con el valor de Basic.
  • La solicitud debe incluir una cabecera de tipo de contenido con el valor de application/x-www-form-urlencoded;charset=UTF-8.
  • El cuerpo de la solicitud debe ser grant_type=client_credentials..

Empecemos con lo básico. Sabemos que necesitamos una petición POST, así que usaremos wp_remote_post(). La función lleva a los parámetros; el primero es la URL, el segundo contiene argumentos opcionales. La URL será https://api.twitter.com/oauth2/token el segundo parámetro para tratar todos los demás requisitos.

$args = array(
    'headers' => array(
        'Authorization' => 'Basic ' . $encoded,
        'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8'
    ),
    'body' => 'grant_type=client_credentials'
);
$response = wp_remote_post( 'https://api.twitter.com/oauth2/token', $args );

Las cabeceras deben ser agregadas como un arreglo, siendo el tipo de cabecera la clave, el valor del miembro del array; el cuerpo debe ser una cadena. Si tienes éxito, deberías ver una respuesta similar a la que se muestra a continuación.

array (size=5)
  'headers' => 
    array (size=23)
      'cache-control' => string 'no-cache, no-store, must-revalidate, pre-check=0, post-check=0' (length=62)
      'content-disposition' => string 'attachment; filename=json.json' (length=30)
      'content-encoding' => string 'deflate' (length=7)
      'content-length' => string '142' (length=3)
      'content-type' => string 'application/json;charset=utf-8' (length=30)
      'date' => string 'Wed, 22 Jul 2015 14:47:37 GMT' (length=29)
      'expires' => string 'Tue, 31 Mar 1981 05:00:00 GMT' (length=29)
      'last-modified' => string 'Wed, 22 Jul 2015 14:47:37 GMT' (length=29)
      'ml' => string 'A' (length=1)
      'pragma' => string 'no-cache' (length=8)
      'server' => string 'tsa_b' (length=5)
      'set-cookie' => string 'guest_id=v1%3A14375720938219946; Domain=.twitter.com; Path=/; Expires=Fri, 21-Jul-2017 14:47:37 UTC' (length=100)
      'status' => string '200 OK' (length=6)
      'strict-transport-security' => string 'max-age=631138519' (length=17)
      'x-connection-hash' => string 'd8b10926f99dwef93rd7edbe5a71a97a' (length=32)
      'x-content-type-options' => string 'nosniff' (length=7)
      'x-frame-options' => string 'SAMEORIGIN' (length=10)
      'x-response-time' => string '34' (length=2)
      'x-transaction' => string 'ef0ebwefweece62ef' (length=16)
      'x-tsa-request-body-time' => string '0' (length=1)
      'x-twitter-response-tags' => string 'BouncerCompliant' (length=16)
      'x-ua-compatible' => string 'IE=edge,chrome=1' (length=16)
      'x-xss-protection' => string '1; mode=block' (length=13)
  'body' => string '{"token_type":"bearer","access_token":"AAAAAAAAAAAAAAAAAAAAAFoafQAAAAAAqg%2BxmuH83hjsod6crH5bKTUX9Arc%3D5dWpp0XCTDjyiXxMC7LDLg8JbzPdGlCsJi2R1qjY1FMksTAFyG"}' (length=155)
  'response' => 
    array (size=2)
      'code' => int 200
      'message' => string 'OK' (length=2)
  'cookies' => 
    array (size=1)
      0 => 
        object(WP_Http_Cookie)[303]
          public 'name' => string 'guest_id' (length=8)
          public 'value' => string 'v1:143757645770219946' (length=21)
          public 'expires' => int 1500648457
          public 'path' => string '/' (length=1)
          public 'domain' => string '.twitter.com' (length=12)
  'filename' => null

La principal característica de todo esto es la señal de acceso que se puede encontrar en el cuerpo de la respuesta. Recuperemos eso ahora usando nuestras prácticas funciones de WordPress. Continuando con nuestro ejemplo anterior, podríamos tomar la clave de acceso usando el siguiente código:

$body = wp_remote_retrieve_body( $response );
$body = json_decode( $body, true );
$access_token = $body['access_token'];

Paso 3: Usa el Token de Bearer

El último paso es simplemente usar este token de Bearer en todas las demás llamadas a la API. Necesitamos agregarlo como una cabecera de «Autorización» con el valor: Bearer [bearer_token]. Hagamos una simple llamada a la API que recupere los últimos tweets de un usuario usando la ruta user_timeline.

$url = 'https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=danielpataki&count=3';
$args = array(
    'headers' => array(
        'Authorization' => 'Bearer ' . $access_token,
    ),
);

$response = wp_remote_get( $url, $args );
$tweets = json_decode( wp_remote_retrieve_body($response), true )

Al final de todo eso, la variable $tweets contendrá una serie de tweets. Puedes usar varias propiedades de esta matriz para mostrar el tweet o manipular los datos.

Conclusión

Como puedes ver, usar el HTTP API de WordPress para conectarse a servicios externos no es tan difícil. Muchas de las modernas API de hoy en día están construidas alrededor de los mismos principios de REST – una vez que aprendas uno, te acostumbrarás a los demás muy rápidamente.

Ten en cuenta que cuando la documentación te pida que uses el cuerpo, usa el cuerpo y cuando te pida la cabecera, solo tienes que añadir tantas como sean necesarias. Luego, mira la respuesta, conviértela en una matriz, toma los datos que necesites y úsalos, es así de simple.

Si alguien ha trabajado antes con una API particularmente buena o mala, o si tienes algunos consejos y trucos para usar el HTTP API de WordPress, háznoslo saber en los comentarios.

Daniel Pataki

Hola, mi nombre es Daniel, soy el CTO de Kinsta. Puede que me conozcas de Smashing Magazine, WPMU Dev, Tuts+ y otras revistas de WordPress/Desarrollo. Aparte de WordPress y PHP, paso la mayor parte de mi tiempo alrededor de Node, React, GraphQL y otras tecnologías en el espacio Javascript. Cuando no estoy trabajando en crear la mejor solución de alojamiento del Universo, colecciono juegos de mesa, juego al futbolín en la oficina, viajo o toco la guitarra y canto en un grupo bastante malo.