Uso de la API Graph

En la información general sobre la API Graph, se exponen los conceptos básicos de su terminología y su estructura. En este documento, se presentan más detalladamente las diferentes operaciones que puedes realizar con la API Graph.

HTTP/1.1

Todas las transferencias de datos cumplen con el protocolo HTTP/1.1 y los extremos deben usar HTTPS. Además, activamos la directiva HSTS includeSubdomains en facebook.com, aunque esto no debería perjudicar las llamadas a la API Graph.

URL del host

Casi todas las solicitudes se pasan a la URL del host graph.facebook.com. Salvo en el caso de las subidas de videos, que usan graph-video.facebook.com.

Tokens de acceso

Los tokens de acceso permiten que la aplicación acceda a la API Graph y, normalmente, realizan dos funciones:

  • Permiten que la aplicación acceda a la información de un usuario sin necesidad de proporcionar su contraseña.
  • Nos permiten identificar la aplicación, el usuario que la utiliza y el tipo de datos a los que este le permitió acceder.

Todos los extremos de la API Graph requieren algún tipo de token de acceso, por lo que todas las solicitudes de acceso deben incluir uno.

Cómo funcionan los tokens

Los tokens de acceso cumplen con el protocolo OAuth 2.0, que permite que las entidades como los usuarios o las páginas los autoricen. Por lo general, esto se realiza a través de una interfaz web. Una vez que reciben la autorización, las aplicaciones pueden usar los tokens para acceder a información específica.

Por ejemplo, esta aplicación solicita a un usuario que le dé permiso para acceder a las fotos, los videos y la dirección de correo electrónico del usuario:

Como puedes ver, esta es una interfaz de Facebook. El usuario acabó de utilizarla para iniciar sesión en su cuenta, lo que nos permitió autenticarlo. Si continúa, intercambiaremos el token antiguo (de aplicación) por uno nuevo (de usuario). De esta manera, la aplicación podrá usar el nuevo token de usuario para hacer solicitudes a la API Graph, aunque solo puede acceder a las fotos, los videos y la dirección de correo electrónico de ese usuario en particular.

Este es un atributo importante de los tokens de acceso. Tanto el identificador de la aplicación como el identificador de usuario están codificados en el token (entre otras cosas), y usamos esos identificadores para hacer un seguimiento de los datos a los que el usuario permitió que acceda la aplicación. Por ejemplo, si inspeccionas el token después de que el usuario conceda el permiso, mostrará esta información:

Los tokens son sumamente valiosos, ya que permiten acceder a los datos del usuario y cualquiera los puede utilizar. Por lo tanto, toma precauciones al usarlos en las consultas. La forma más fácil de hacerlo es usando el inicio de sesión con Facebook para administrarlos.

Inicio de sesión con Facebook

El protocolo OAuth 2.0 conlleva muchos redireccionamientos, avisos de inicio de sesión e intercambio de tokens, así que, para facilitarte las cosas, creamos el producto inicio de sesión con Facebook. El inicio de sesión con Facebook cuenta con funciones y métodos fáciles de usar para todos los SDK. Por tal razón, el trabajo con tokens de acceso es mucho más simple que si crearas tu propia solución.

Para obtener más información sobre los tokens de acceso y el inicio de sesión con Facebook, o bien para aprender a crear tu propia solución, consulta la documentación sobre el inicio de sesión con Facebook.

Lectura

Nodos

Las operaciones de lectura comienzan casi siempre con un nodo, que es un objeto individual con un identificador único. Por ejemplo, existen muchos objetos de nodo "Page", cada uno con un identificador único, pero la página de Coca-Cola es la única con el identificador 820882001277849. Para leer cualquier nodo, se consulta un identificador de objeto específico, así que, para leer el nodo de la página de Coca-Cola, consultarías el suyo:

GET https://graph.facebook.com/820882001277849

Esta solicitud devolvería los siguientes campos (propiedades de nodos) de manera predeterminada, con un formato JSON:

{
  "name": "Coca-Cola",
  "id": "820882001277849"
}

Perímetros

Los nodos tienen perímetros, que normalmente devuelven colecciones de otros nodos adjuntos. Para leer un perímetro, debes incluir el identificador del nodo y el nombre del perímetro en la ruta de acceso. Por ejemplo, los nodos /page tienen un perímetro /feed, que puede devolver todos los nodos "Post" en una página. En este ejemplo, se muestra cómo usar el perímetro para obtener todas las publicaciones en la página de Coca-Cola:

GET https://graph.facebook.com/820882001277849/feed

La respuesta JSON tendría el siguiente aspecto:

{
  "data": [
    {
      "created_time": "2017-12-08T01:08:57+0000",
      "message": "Love this puzzle. One of my four coke puzzles",
      "id": "820882001277849_1805191182846921"
    },
    {
      "created_time": "2017-12-07T20:06:14+0000",
      "message": "You need to add grape as a flavor for Coke in your freestyle machines.",
      "id": "820882001277849_1804966026202770"
    },
    {
      "created_time": "2017-12-07T01:29:12+0000",
      "message": "Plz play the old commercial’s with the polar bears. Would be nice to see them this holiday",
      "id": "820882001277849_1804168469615859"
    }
  ]
}

Observa que las respuestas no solo contienen los identificadores de los nodos "Post" en la colección, sino, también, los campos created_time y message, lo cual es normal. La mayoría de los perímetros incluirá uno o más campos de manera predeterminada.

Campos

Los campos son propiedades de nodos. Al consultar un nodo, este devuelve un conjunto de campos de manera predeterminada, como se muestra en los ejemplos anteriores. Sin embargo, puedes especificar los campos que quieres que se devuelvan usando el parámetro fields y enumerando cada uno. Esto anulará los campos predeterminados y devolverá solo los que especifiques, así como el identificador del objeto, que se devuelve siempre.

Por ejemplo, en la referencia sobre el nodo "Page", se indican los campos que puedes solicitar al leer un nodo "Page". Si quieres obtener los campos about, fan_count y website para la página de Coca-Cola, puedes hacer lo siguiente:

GET https://graph.facebook.com/820882001277849
    ?fields=about,fan_count,website

Esto devolverá la siguiente respuesta:

{
  "about": "Welcome to the happiest Facebook page on, um, Facebook.",
  "fan_count": 106714402,
  "website": "http://coca-cola.com",
  "id": "820882001277849"
}

Los perímetros, que normalmente devuelven colecciones de objetos, también lo hacen con campos sobre cada objeto en la colección. Supongamos que usaste el perímetro /photos para obtener todos los nodos "Photo" en la página de Coca-Cola:

GET https://graph.facebook.com/820882001277849/photos

Se generará una respuesta parecida a esta:

{
  "data": [
    {
      "created_time": "2016-08-23T13:12:10+0000",
      "id": "1308573619175349"
    },
    {
      "created_time": "2016-08-05T22:34:19+0000",
      "id": "1294456907253687"
    },
    {
      "created_time": "2016-04-29T16:17:02+0000",
      "id": "1228552183844160"
    }
  ]
}

Como puedes ver, el perímetro /photos devolverá de manera predeterminada una colección de identificadores de nodos "Photo", así como la propiedad created_time para cada foto. Al igual que con los nodos, puedes usar el parámetro fields para especificar los campos que quieres que se devuelvan para cada uno de los objetos devueltos en la colección.

Supongamos que quieres obtener los campos (de URL) height, width y link para cada nodo "Photo" que devolvió el perímetro /photos:

GET https://graph.facebook.com/820882001277849/photos
      ?fields=height,width,link

La respuesta tendrá el siguiente aspecto:

{
  "data": [
    {
      "height": 720,
      "width": 720,
      "link": "https://www.facebook.com/CocaColaUnitedStates/photos/a.820887414610641.1073741825.820882001277849/1308573619175349/?type=3",
      "id": "1308573619175349"
    },
    {
      "height": 720,
      "width": 720,
      "link": "https://www.facebook.com/CocaColaUnitedStates/photos/a.820887414610641.1073741825.820882001277849/1294456907253687/?type=3",
      "id": "1294456907253687"
    },
    {
      "height": 180,
      "width": 180,
      "link": "https://www.facebook.com/CocaColaUnitedStates/photos/a.820887414610641.1073741825.820882001277849/1228552183844160/?type=3",
      "id": "1228552183844160"
    }
  ]
}

Ten presente que también puedes especificar un perímetro con el parámetro fields, lo que es útil al usar una expansión de campo.

Expansión de campo

Si por casualidad probaste la consulta GET /page/photos anterior en el explorador de la API Graph, quizá hayas notado que la solicitud devolvió más de tres objetos y que, además, paginó los resultados. Esto es habitual en la mayoría de los perímetros. Pronto veremos cómo recorrer los resultados, pero, por el momento, detengámonos en la expansión de campo, que no solo te permite realizar consultas anidadas, sino, también, limitar y ordenar los resultados.

Limitación de los resultados

Al limitar los resultados, puedes controlar la cantidad de objetos que se devuelven en cada conjunto de resultados paginados. Para hacerlo, agrega un argumento .limit() a cualquier campo o perímetro.

Por ejemplo, si realizas una solicitud "GET" en el perímetro /feed de la página de Coca-Cola, se devolverán cientos de publicaciones. Puedes limitar la cantidad de publicaciones que se devuelven para cada página de resultados de la siguiente manera:

GET https://graph.facebook.com/820882001277849
    ?fields=feed.limit(3)

Esto devuelve todas las publicaciones de la página de Coca-Cola, pero limita a tres la cantidad de objetos en cada página de resultados. Observa que, en vez de especificar el perímetro "Feed" en la URL de la ruta de acceso (/page/feed), lo especificas en el parámetro fields (?fields=feed), que te permite anexar el argumento .limit(3).

Estos son los resultados de la consulta:

{
  "feed": {
    "data": [
      {
        "created_time": "2017-12-12T01:24:21+0000",
        "message": "This picture of my grandson with Santa screams Coca Cola",
        "id": "820882001277849_1809387339093972"
      },
      {
        "created_time": "2017-12-11T23:40:17+0000",
        "message": ":)",
        "id": "820882001277849_1809316002434439"
      },
      {
        "created_time": "2017-12-11T23:31:38+0000",
        "message": "Thought you might enjoy this.  My horse loves Coke!",
        "id": "820882001277849_1809310929101613"
      }
    ],
    "paging": {
      "cursors": {
        "before": "Q2c4U1pXNTBYM0YxWlhKNVgzTjBiM0o1WDJsa0R5UTRNakE0T0RJd01ERXlOemM0TkRrNkxUVXdPRE16TXpVM01EQXpNVFUwTkRRME5Ua1BER0ZA3YVY5emRHOXllVjlwWkE4ZA09ESXdPRGd5TURBeE1qYzNPRFE1WHpFNE1Ea3pPRGN6TXprd09UTTVOeklQQkhScGJXVUdXaTh2eFFFPQZDZD",
        "after": "Q2c4U1pXNTBYM0YxWlhKNVgzTjBiM0o1WDJsa0R5TTRNakE0T0RJd01ERXlOemM0TkRrNk1UTTJORE01T0RVNU1UZAzVPRGMyTnpFNE1BOE1ZAWEJwWDNOMGIzSjVYMmxrRHlBNE1qQTRPREl3TURFeU56YzRORGxmTVRnd09USXdOamsxTlRjM09EWTNOdzhFZAEdsdFpRWmFMdk9HQVE9PQZDZD"
      },
      "next": "https://graph.facebook.com/820882001277849/feed?access_token=valid_token_goes_here"
    }
  },
  "id": "820882001277849"
}

Como puedes ver, solo aparecen tres objetos en esta página de resultados paginados, pero la respuesta incluyó un campo next y una URL que puedes usar para recuperar la siguiente página.

Ordenar los resultados

Puedes ordenar los resultados según la hora de creación del objeto. Para hacerlo, usa un argumento .order() con uno de los siguientes valores en un campo o perímetro.

  • chronological: ordena los resultados con los objetos creados más antiguos en primer lugar.
  • reverse_chronological: ordena los resultados con los objetos creados más nuevos en primer lugar.

Por ejemplo, obtengamos todos los comentarios en una de las publicaciones con video de la página de Coca-Cola (1809938745705498), ordenemos los resultados cronológicamente (primero los más antiguos) y limitemos a tres la cantidad de objetos por resultado paginado:

GET https://graph.facebook.com/1809938745705498
    ?fields=comments.order(chronological).limit(3)

De nuevo, observa que, para usar un argumento en un perímetro, debes especificarlo en el parámetro fields. Además, como puedes ver, es posible combinar los argumentos .limit() y .order() en un solo campo o perímetro.

Estos son los resultados:

{
  "comments": {
    "data": [
      {
        "created_time": "2017-12-12T14:12:20+0000",
        "message": ":) :) :)",
        "id": "1809938745705498_1809939942372045"
      },
      {
        "created_time": "2017-12-12T14:14:03+0000",
        "message": "seasons greetings!",
        "id": "1809938745705498_1809941802371859"
      },
      {
        "created_time": "2017-12-12T14:14:11+0000",
        "message": "My bestie <3",
        "id": "1809938745705498_1809941879038518"
      }
    ],
    "paging": {
      "cursors": {
        "before": "WTI5dGJXVnVkRjlqZAFhKemIzSTZANVGd3T1Rrek9UZAzROVGN3TlRNNE5Eb3hOVEV6TURnM09UTTIZD",
        "after": "WTI5dGJXVnVkRjlqZAFhKemIzSTZANVGd4TURBd09UazROVFk1T0RNM05Eb3hOVEV6TURreU5qQXoZD"
      },
      "next": "https://graph.facebook.com/1809938745705498/comments?access_token=valid_token_goes_here"
    }
  },
  "id": "1809938745705498"
}

Publicación

Con la mayoría de los perímetros, puedes publicar objetos en una colección de un nodo mediante una solicitud "POST" en el perímetro respectivo. Por ejemplo, puedes publicar un comentario en una foto usando el perímetro /comments del nodo "Photo":

POST https://graph.facebook.com
  /1809938745705498
    /comments
      ?message=Awesome!

Si la operación se realiza correctamente, la mayoría de los perímetros devolverán el identificador del objeto que acabas de publicar, que suele ser una combinación de aquel con el que se publicó el objeto y una nueva cadena de identificador:

{
  "id": "1809938745705498_1810399758992730"
}

Para publicar, normalmente se requieren permisos adicionales. Por lo tanto, consulta la documentación de referencia de cada perímetro para determinar los permisos que necesites.

El token de acceso que se use para publicar el objeto puede afectar su apariencia. Si se usa un token de acceso a la página, aparecerá como si la página hubiera publicado el objeto, mientras que un token de acceso del usuario hará que se vea como si lo hubiera hecho una persona.

Muchos perímetros también son compatibles con funciones avanzadas, por ejemplo, la lectura después de escritura, que te permite leer inmediatamente un objeto publicado recientemente, y la publicación por lotes, con la que puedes encadenar varias operaciones de publicación.

Actualización

Puedes realizar operaciones de actualización en un nodo existente mediante solicitudes POST. Por ejemplo, para actualizar el campo message en un comentario existente, puedes hacer lo siguiente:

POST https://graph.facebook.com
  /1809938745705498_1810399758992730
    ?message=Happy%20Holidays!

Si la operación se realiza correctamente, el nodo devolverá un campo success y un valor de true:

{
  "success": true
}

Al igual que las operaciones de publicación, las de actualización requieren permisos adicionales, que se enumeran en la documentación de referencia de cada nodo. Además, al igual que la mayoría de los perímetros, muchos nodos son compatibles con la lectura después de escritura.

Eliminación

Normalmente, puedes eliminar un nodo mediante una operación "DELETE":

DELETE https://graph.facebook.com
  /1809938745705498_1810399758992730

Si la operación se realiza correctamente, el nodo devolverá un campo success y un valor de true:

{
  "success": true
}

Por lo general, solo puedes eliminar los nodos que creaste, pero consulta la guía de referencia de cada uno para conocer los requisitos de las operaciones de eliminación.

Para admitir a los clientes que no tengan compatibilidad con todos los métodos HTTP, puedes enviar una solicitud POST al nodo e incluir el parámetro method=delete y el valor para reemplazar el método HTTP:

POST https://graph.facebook.com
  /1809938745705498_1810399758992730
    ?method=delete

Recorrer resultados de páginas

Cuando haces una solicitud de API a un nodo o perímetro, por lo general, no recibes todos los resultados de la solicitud en una sola respuesta. Esto se debe a que algunas respuestas contienen miles de objetos, por lo que la mayoría de las respuestas están paginadas de forma predeterminada.

Paginación basada en el cursor

El método de paginación más eficiente es el basado en el cursor y se debe usar siempre que sea posible. Un cursor hace referencia a una cadena de caracteres aleatoria que marca un elemento específico en una lista de datos. A menos que se elimine este elemento, el cursor siempre apunta a la misma parte de la lista, pero se invalidará si se elimina un elemento. Por lo tanto, tu aplicación no debe almacenar cursores ni suponer que seguirán siendo válidos en el futuro.

Al leer un perímetro que admite la paginación de cursor, verás la siguiente respuesta JSON:

{
  "data": [
     ... Endpoint data is here
  ],
  "paging": {
    "cursors": {
      "after": "MTAxNTExOTQ1MjAwNzI5NDE=",
      "before": "NDMyNzQyODI3OTQw"
    },
    "previous": "https://graph.facebook.com/me/albums?limit=25&before=NDMyNzQyODI3OTQw"
    "next": "https://graph.facebook.com/me/albums?limit=25&after=MTAxNTExOTQ1MjAwNzI5NDE="
  }
}

Un perímetro con paginación de cursor admite los siguientes parámetros:

  • before: este es el cursor que apunta al inicio de la página de datos que se devolvió.
  • after: este es el cursor que apunta al final de la página de datos que se devolvió.
  • limit: este es el número máximo de objetos que se pueden devolver. Es posible que una consulta devuelva un número menor que el valor de limit debido a los filtros. Que el número de resultados sea menor que el número de limit no indica necesariamente que tu consulta llegó al final de la lista de datos, obtén el resultado en ausencia de next, como se describe a continuación. Por ejemplo, si estableces el valor de limit en diez y se devuelven nueve resultados, es posible que haya más datos disponibles pero que un elemento se haya eliminado debido al filtro de privacidad. Por motivos de rendimiento, algunos perímetros tienen un máximo en el valor limit. En todos los casos, la API devuelve los enlaces de paginación correctos.
  • next: el extremo de API Graph que devolverá la siguiente página de datos. Si no se incluye, esta es la última página de datos. Debido a la forma en que funciona la paginación con visibilidad y privacidad, es posible que una página parezca vacía, pero incluya un enlace de paginación "next". Debes dejar de paginar cuando el enlace "next" no aparezca más.
  • previous: el extremo de API Graph que devolverá la página de datos anterior. Si no se incluye, esta es la primera página de datos.

No almacenes los cursores. Los cursores pueden perder su validez muy rápidamente si se agregan o eliminan elementos.

Paginación basada en el tiempo

La paginación basada en el tiempo se utiliza para navegar por los datos de resultados con marcas de tiempo de UNIX que apuntan a horas específicas en una lista de datos.

Al utilizar un extremo que utiliza la paginación basada en el tiempo, verás la siguiente respuesta JSON:

{
  "data": [
     ... Endpoint data is here
  ],
  "paging": {
    "previous": "https://graph.facebook.com/me/feed?limit=25&since=1364849754",
    "next": "https://graph.facebook.com/me/feed?limit=25&until=1364587774"
  }
}

Un perímetro paginado por tiempo admite los siguientes parámetros:

  • until: Una marca de tiempo de Unix o un valor de datos strtotime que apunta al final del intervalo de datos basados en el tiempo.
  • since: Una marca de tiempo de Unix o un valor de datos de strtotime que apunta al inicio del intervalo de datos basados en el tiempo.
  • limit: este es el número máximo de objetos que se pueden devolver. Es posible que una consulta devuelva un número menor que el valor de limit debido a los filtros. Que el número de resultados sea menor que el número de limit no indica necesariamente que tu consulta llegó al final de la lista de datos, obtén el resultado en ausencia de next, como se describe a continuación. Por ejemplo, si estableces el valor de limit en diez y se devuelven nueve resultados, es posible que haya más datos disponibles pero que un elemento se haya eliminado debido al filtro de privacidad. Por motivos de rendimiento, algunos perímetros tienen un máximo en el valor limit. En todos los casos, la API devuelve los enlaces de paginación correctos.
  • next: el extremo de API Graph que devolverá la siguiente página de datos.
  • previous: el extremo de API Graph que devolverá la página de datos anterior.

Para obtener resultados coherentes, especifica los parámetros since y until. Además, te recomendamos que la diferencia de tiempo sea de seis meses como máximo.

Paginación basada en el intervalo

Puedes utilizar la paginación de intervalo cuando no te importe la cronología y solo quieras que se devuelva un número específico de objetos. Solo debe utilizarse si el perímetro no admite la paginación de cursor o basada en el tiempo.

Un perímetro paginado de intervalo admite los siguientes parámetros:

  • offset: comienza el inicio de cada página con el número especificado.
  • limit: este es el número máximo de objetos que se pueden devolver. Es posible que una consulta devuelva un número menor que el valor de limit debido a los filtros. Que el número de resultados sea menor que el número de limit no indica necesariamente que tu consulta llegó al final de la lista de datos, obtén el resultado en ausencia de next, como se describe a continuación. Por ejemplo, si estableces el valor de limit en diez y se devuelven nueve resultados, es posible que haya más datos disponibles pero que un elemento se haya eliminado debido al filtro de privacidad. Por motivos de rendimiento, algunos perímetros tienen un máximo en el valor limit. En todos los casos, la API devuelve los enlaces de paginación correctos.
  • next: el extremo de API Graph que devolverá la siguiente página de datos. Si no se incluye, esta es la última página de datos. Debido a la forma en que funciona la paginación con visibilidad y privacidad, es posible que una página parezca vacía, pero incluya un enlace de paginación "next". Debes dejar de paginar cuando el enlace "next" no aparezca más.
  • previous: el extremo de API Graph que devolverá la página de datos anterior. Si no se incluye, esta es la primera página de datos.

Ten en cuenta que, si se agregan nuevos objetos a la lista de elementos que se está paginando, el contenido de cada página basada en intervalo cambiará.

La paginación basada en intervalo no es compatible con las llamadas a la API. Para obtener resultados coherentes, te recomendamos paginar mediante los enlaces anteriores o siguientes que devolvemos en la respuesta.

En el caso de objetos para los que se devuelven grandes números de artículos, como [comentarios](/docs/graph-api/reference/object/comments) que pueden rondar las decenas de miles, es posible que encuentres límites al realizar la paginación. La API devolverá un error cuando tu aplicación haya alcanzado el límite del cursor:

{
  "error": {
    "message": "(#100) The After Cursor specified exceeds the max limit supported by this endpoint",
    "type": "OAuthException",
    "code": 100
  }
}