图谱 API 的使用方法

图谱 API 是存取 Facebook 社交关系图谱数据的主要方式。它是一种以 HTTP 为基础的轻量级 API,可用于查询数据、发布新动态、上传照片和完成一款应用可能需要执行的各种其他任务。本指南介绍了如何在图谱 API 中完成所有这些操作。

基本信息

图谱 API 概览中包含图谱 API 术语和结构的基本信息。以下各部分详细说明了可使用 API 执行的不同操作。

读取

向相关端点发送 HTTP GET 请求,即可读取图谱 API 中的所有节点和连线。例如,如果您想检索当前用户的信息,可以按照下方的指示发出 HTTP GET 请求:

GET /v2.5/me HTTP/1.1
Host: graph.facebook.com

大多数 API 调用都必须使用访问口令签名。您可以查看图谱 API 参考文档,了解要读取的节点或连线,确定该访问口令中需要哪些权限。您也可以使用图谱 API 探索工具快速生成口令,以便尝试使用 API 和了解它的工作原理。

/me 节点是将转译成用户 user_id(或 Facebook 主页的 page_id)的特殊端点,该用户的访问口令当前正被用于调用 API。如果您有用户访问口令,可以使用以下命令检索用户的所有照片:

GET graph.facebook.com
  /me/photos

您收到的响应视读取的节点或连线而异,但一般形式如下:

{
   "fieldname": {field-value},
   ....
}

选择字段

默认情况下,查询时不会返回节点或连线中的所有字段。您可以使用 fields 查询参数选择要返回的字段或连线。这样做能大幅提升调用 API 的效率和速度。

例如,以下使用您自己的用户访问口令的图谱 API 调用 https://graph.facebook.com/me?fields=id,name,picture 仅会返回个人主页编号、名称和头像:

GET graph.facebook.com/me?fields=id,name,picture

排序

您可以按时间顺序排列特定数据集。例如,可使用 reverse_chronological 键按时间倒序排列照片评论:

GET graph.facebook.com
  /{photo-id}?
    fields=comments.order(reverse_chronological)

order 必须是以下值中的一个:

  • chronological
  • reverse_chronological

网址查找

大多数对象都能通过编号查找,但有时候可能没有编号,只有网址可用于查找对象。

您可以使用 2.1 版中引入的网址节点返回开放图谱对象的网址编号,或查找与应用链接网址关联的数据。

参阅 Facebook 应用链接文档,详细了解如何使用索引 API 查找应用链接数据。

修改 API 请求

某些 API 端点可以与修改请求的附加参数配合使用。这些修改参数执行的操作性质各不相同,所以我们在相应的各个 API 参考文档中分别记录了各个修改参数。以下是可与大多数端点配合使用的常见修改参数的列表。

名称 说明 类型

return_ssl_resources

需要通过安全连接 (HTTPS) 返回图片时使用,避免浏览器中出现混合内容警告。

bool

locale

应用需要使用特定区域设置(如可用)的语言检索本地化内容时使用。

Locale

用于分页自检的其他修改参数见下文所示。

发出嵌套请求

通过图谱 API 的字段扩展功能,您可以有效地将多个图谱查询嵌套入单次调用中。包括大多数广告 API 在内的一些资源无法在部分或全部连接上使用字段扩展。

例如,您可以在一次调用中请求前 K 个相册的前 N 张照片。响应将保持数据层级,因此开发者无需在客户端上将数据编排在一起。

此功能与批量请求不同,批量请求可让您在单次请求中执行多个彼此独立的图谱 API 调用。

以下是字段扩展采用的一般形式:

GET graph.facebook.com
  /{node-id}?
    fields=<first-level>{<second-level>}

<first-level>在此示例中, 是来自父节点的一个或多个(逗号分隔)字段或连线。 <second-level>是来自一级节点的一个或多个(逗号分隔)字段或连线。

此处可以实现的嵌套层级数量没有限制。您也可以在各字段或连线中使用 .limit(n) 参数来限制要获取的对象数量。

看到实际运用更容易理解,因此我们在下方提供了一个查询示例,检索由某位用户创建的最多五个相册,以及他们的动态中最新的五个帖子。

GET graph.facebook.com
  /me?
    fields=albums.limit(5),posts.limit(5)

然后我们可以稍加扩展,将每个相册对象的检索内容增加为前两张照片以及每张照片中圈出的用户:

GET graph.facebook.com
  /me?
    fields=albums.limit(5){name, photos.limit(2)},posts.limit(5)

现在我们可以再次扩展,检索每张照片的名称、图片网址和圈出的用户:

GET graph.facebook.com
  /me?
    fields=albums.limit(5){name, photos.limit(2){name, picture, tags.limit(2)}},posts.limit(5)

下面我们来看看使用基于游标的分页的示例:

GET graph.facebook.com
  /me?fields=albums.limit(5){name,photos.limit(2).after(MTAyMTE1OTQwNDc2MDAxNDkZD){name,picture,tags.limit(2)}},posts.limit(5)

您可以看到字段扩展如何跨节点、连线和字段运作,并在单次请求中返回非常复杂的数据。

遍历分页结果

当您向节点或连线发出 API 请求时,通常不会在单个响应中收到该请求的全部结果。这是因为某些响应可能包含数千个对象,因此大多数响应都将默认分页。

基于游标的分页

基于游标的分页是最有效的分页方法,应尽量使用这种方法。游标是指标记数据列表中特定项目的一个随机字符串。该项目未被删除时,游标将始终指向列表的相同部分,项目被删除时游标即失效。因此,您的应用不应存储游标,也不能假定它们在未来有效。

读取支持游标分页的连线时,您将看到以下 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="
  }
}

游标分页的连线支持以下参数:

  • before:这是指向已返回的数据页面开头的游标。
  • after:这是指向已返回的数据页面末尾的游标。
  • limit:这是可能返回的最大对象数量。由于应用了筛选条件,查询操作返回的值可能低于 limit 值。不要依赖小于 limit 值的结果数来指明您的查询到达数据列表的末尾,请使用下面描述的不包含 next 的方式来指明到达数据列表的末尾。例如,如果您将 limit 设置为 10 但返回 9 个结果,则可能有更多数据可用,但是有一个项目由于隐私筛选条件而被删除。 为提升性能,也可为某些连线设置最大的 limit 值。所有情况下,API 都将返回正确的分页链接。
  • next:将返回下一页数据的图谱 API 端点。如果未包含,则显示的是最后一页数据。根据分页的可见性和隐私,页面可能为空,但包含“next”分页链接。“next”链接不再出现时,应停止分页。
  • previous:将返回上一页数据的图谱 API 端点。如果未包含,则显示的是第一页数据。

请勿存储游标。如果添加或删除了项目,游标可能很快就会失效。

基于时间的分页

时间分页使用指向数据列表中的特定时间的 Unix 时间戳在结果数据中导航。

使用采用时间分页的端点时,您将看到以下 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"
  }
}

基于时间的连线支持以下参数:

  • until:指向基于时间的数据范围末尾的 Unix 时间戳或 strtotime 数据值。
  • since:指向基于时间的数据范围开头的 Unix 时间戳或 strtotime 数据值。
  • limit:这是可能返回的最大对象数量。由于应用了筛选条件,查询操作返回的值可能低于 limit 值。不要依赖小于 limit 值的结果数来指明您的查询到达数据列表的末尾,请使用下面描述的不包含 next 的方式来指明到达数据列表的末尾。例如,如果您将 limit 设置为 10 但返回 9 个结果,则可能有更多数据可用,但是有一个项目由于隐私筛选条件而被删除。 为提升性能,也可为某些连线设置最大的 limit 值。所有情况下,API 都将返回正确的分页链接。
  • next:将返回下一页数据的图谱 API 端点。
  • previous:将返回上一页数据的图谱 API 端点。

要获得一致的结果,需要指定 sinceuntil 参数。此外,建议时间差异最大为 6 个月。

基于偏移的分页

如果时间顺序对您不重要,只需要返回特定数量的对象,则可以使用偏移分页。只有连线不支持基于游标或时间的分页时,才能使用这种分页方法。

基于偏移分页的连线支持以下参数:

  • offset:这将按指定的数字偏移每个页面的开头。
  • limit:这是可能返回的最大对象数量。由于应用了筛选条件,查询操作返回的值可能低于 limit 值。不要依赖小于 limit 值的结果数来指明您的查询到达数据列表的末尾,请使用下面描述的不包含 next 的方式来指明到达数据列表的末尾。例如,如果您将 limit 设置为 10 但返回 9 个结果,则可能有更多数据可用,但是有一个项目由于隐私筛选条件而被删除。 为提升性能,也可为某些连线设置最大的 limit 值。所有情况下,API 都将返回正确的分页链接。
  • next:将返回下一页数据的图谱 API 端点。如果未包含,则显示的是最后一页数据。根据分页的可见性和隐私,页面可能为空,但包含“next”分页链接。“next”链接不再出现时,应停止分页。
  • previous:将返回上一页数据的图谱 API 端点。如果未包含,则显示的是第一页数据。

请注意,如果正分页的项目列表添加了新的对象,每个基于偏移的页面的内容都将发生更改。

并非所有 API 调用都支持基于偏移的分页。要获得一致的结果,建议您使用我们在响应中返回的 previous/next 链接分页。

发出大请求

某些图谱 API 端点可能带有非常大的参数。 如果您的请求最终超过两千个字符,您可能会看到服务器错误,因为我们的服务器会拒绝非常大的 GET 请求。

根据最佳实践,大请求应使用 POST 请求而不是 GET 请求,并添加 method=GET 参数。 执行此操作后,POST 将被解读为 GET

发出多个请求

图谱 API 的标准版本经设计可非常轻松地获取单个对象的数据,以及浏览对象之间的连接。它还包含有限的功能,可以同时检索多个对象的数据。

如果您的应用需要一次访问大量数据,或您需要一次性修改多个对象,通常更有效的方法是批量处理查询而不是发出多个单独的 HTTP 请求。

为实现这一点,图谱 API 支持多种功能,包括多个编号查找和批量处理。批量请求的说明请参阅单独的指南,但您可以通过下文详细了解多个编号查找。

多个编号读取请求

您可以发出检索多个节点的单次 GET 请求,方法是使用 ?ids 端点及这些节点的对象编号。例如,要在单次请求中查找 Facebook 开发者主页和当前会话用户,您可以使用以下图谱 API 调用:

GET graph.facebook.com
  /?ids=platform,me

它与以下单独 API 请求等同:

GET graph.facebook.com
  /platform
  
GET graph.facebook.com
  /me

返回的数据如下:

{
  "me": {
    "id": "1234567890"
    ... // Other fields
  }, 
  "platform": {
    "id": "19292868552"
    ... // Other fields
  }
}

这也适用于连线,只要所有请求的编号都有请求的连线。例如:

GET graph.facebook.com
  /photos?ids={user-id-a},{user-id-b}

与以下单独 API 请求等同:

GET graph.facebook.com
  /{user-id-a}/photos
  
GET graph.facebook.com
  /{user-id-b}/photos

返回的数据如下:

{
  "{user-id-a}": {
    "data": [
      {
        "id": "12345", 
        "picture": "{photo-url}", 
        "created_time": "2014-07-15T15:11:25+0000"
      }
      ... // More photos
    ]
  },
  "{user-id-b}": {
    "data": [
      {
        "id": "56789", 
        "picture": "{photo-url}", 
        "created_time": "2014-01-15T12:24:47+0000"
      }
      ... // More photos
    ]
  }, 
}

请注意:虽然字段筛选、字段扩展和限制可以用于多个编号查找,但如果其中一个对象不包含任意请求的字段,您将收到错误提示。例如,如果您使用此方法查找 Page 和 User,并将筛选条件设置为 fields=id,picture,gender,请求将失败,因为主页没有 gender 字段。

自检

图谱 API 支持节点自检,这让您能提前看到节点拥有的所有连线,而无需知道节点的类型。要获得这一信息,向图谱 API 请求添加 metadata=1

GET graph.facebook.com
  /{node-id}?
    metadata=1

生成的 JSON 将包含 metadata 属性,其中列出指定节点的所有受支持连线:

{
   "name": {node-name},
   "metadata": {
      "connections": {
         "feed": "http://graph.facebook.com/me/feed",
         "picture": "https://graph.facebook.com/me/picture",
         ....
      }
      "fields": [
        {
          "name": "id",
          "description": "The user's Facebook ID. No `access_token` required. `string`."
        },
        ....
      ],
      "type": "user"
   }
}

发布

图谱 API 中的大多数节点都有可作为发布目标的连线,例如 /{user-id}/feed/{album-id}/photos。所有图谱 API 发布都一样:向相关连线发出 HTTP POST 请求并附加所有必要的参数。例如,要以某位用户的身份发帖,则可根据下方所示发出 HTTP POST 请求:

POST graph.facebook.com
  /{user-id}/feed?
    message={message}&
    access_token={access-token}

所有发布调用必须使用访问口令签名。您可以查看图谱 API 参考文档,了解要发布内容的节点,确定该访问口令中需要哪些权限

可作为发布目标的连线很多。请查看参考文档,了解每个节点的详细信息。

图谱 API 常见情况指南包含一些常见发布情况的其他信息。

发出多个请求

您可以使用批量请求将发布调用与读取调用链接起来。如需了解其他信息,请参阅发出多个 API 请求

先写入后读取

许多连线都支持先写入后读取功能。请参阅每个端点的参考文档,了解各个端点是否支持先写入后读取功能,以及可使用哪些字段。

更新

所有图谱 API 更新都一样:向相关节点发出 HTTP POST 请求并附加所有更新的参数:

POST graph.facebook.com
  /{node-id}?
    {updated-field}={new-value}&
    access_token={access-token}

所有更新调用都必须使用访问口令签名,且访问口令拥有发布至该端点所需的权限,具体请参阅要更新的节点的图谱 API 参考文档

先写入后读取

许多连线都支持先写入后读取功能。请参阅每个端点的参考文档,了解各个端点是否支持先写入后读取功能,以及可使用哪些字段。

删除

您可以从图谱删除节点,方法是向节点发出 HTTP DELETE 请求:

DELETE graph.facebook.com
  /{node-id}?
    access_token=...

一般来说,应用只能删除自己创建的内容。查看参考指南详细了解节点或连线。

要支持对 HTTP 方法部分支持的客户端,您可以向端点发出 POST 请求并附加参数 method=delete,以便替代 HTTP 方法。例如,您可以通过发出以下请求来删除评论:

POST graph.facebook.com
  /{comment-id}?
    method=delete

先写入后读取

对于创建和更新端点,图谱 API 可以立即读取成功发布或更新的对象,并返回相应读取端点支持的所有字段。

要使用此功能,应在请求中添加 fields 参数,并列出希望返回的字段。例如,要向用户的动态发布消息“Hello”,您可以发出下列请求:

POST graph.facebook.com
  /126577551217199/feed?
    message=Hello&
    fields=created_time,from,id,message,permalink_url

此请求会以 JSON 格式的响应返回指定字段,如下所示:

{
  "created_time": "2017-04-06T22:04:21+0000",
  "from": {
    "name": "Jay P Jeanne",
    "id": "126577551217199"
  },
  "id": "126577551217199_122842541590700",
  "message": "Hello",
  "permalink_url": "https://www.facebook.com/126577551217199/posts/122842541590700",
}

请参阅每个端点的参考文档,了解各个端点是否支持先写入后读取功能,以及可使用哪些字段。

错误

如果读取因任何原因失败(如请求的字段不存在),图谱 API 将给出标准错误响应。此外,响应还将包含一个 original_response 属性,其值为对应端点正常情况下在读取成功时返回的内容。

例如,此请求包含无效字段:

POST graph.facebook.com
  /126577551217199/feed?
    message=Hello&
    fields=permalink_urls

将收到如下响应:

{
  "error": {
    "message": "(#100) Tried accessing nonexisting field (permalink_urls) on node type (Post)",
    "type": "FacebookApiException",
    "code": 100,
    "fbtrace_id": "AzMnKh6NRKY",
    "original_response": {
      "id": "126577551217199_122842541590700"
    }
  }
}

您可以使用 /search 端点搜索社交关系图谱中的多个公开对象。搜索的语法是:

GET graph.facebook.com
  /search?
    q={your-query}&
    type={object-type}

所有图谱 API 搜索查询都需要在请求中加入访问口令。您需要用户访问口令来执行搜索。

可用的搜索类型

我们支持以下类型的搜索:

类型 说明 “q”值

user

搜索用户(前提是用户允许搜索他们的名称)。

名称

page

搜索主页。

名称

event

搜索活动。

名称

group

搜索小组。

名称

place

搜索地点。您可以通过添加 center 参数(带经纬度)和可选的 distance 参数(以米为单位),将搜索范围缩小到特定位置和距离:

名称

placetopic

返回可能的地点主页主题及其编号的列表。与 topic_filter=all 参数配合使用可获取完整列表。

ad_*

可用于查找定位选项的不同搜索选项集合。

请参阅定位选项

示例:

GET graph.facebook.com
  /search?
    q=coffee&
    type=place&
    center=37.76,-122.427&
    distance=1000

处理错误

向 Fackbook API 发出的请求可能会产生多种不同的错误响应。以下主题说明了恢复策略,并列出错误值和相应的最常用恢复策略。

接收错误代码

以下展示了 API 请求失败导致的一个常见错误响应:

{
  "error": {
    "message": "Message describing the error", 
    "type": "OAuthException", 
    "code": 190,
    "error_subcode": 460,
    "error_user_title": "A title",
    "error_user_msg": "A message",
    "fbtrace_id": "EJplcsCHuLu"
  }
}
  • message:人类可读的错误说明。
  • code:错误代码。下方列出了常见值以及常用恢复策略。
  • error_subcode:关于错误的其他信息。下方列出了常见值。
  • error_user_msg:向用户显示的消息。消息语言以 API 请求的区域设置为依据。
  • error_user_title:代表对话框的标题(如显示)。消息语言以 API 请求的区域设置为依据。
  • fbtrace_id:内部支持标识符。报告与图谱 API 调用相关的缺陷时,提供 fbtrace_id 可帮助我们查找关于调试的日志数据。

错误代码

代码或类型 名称 解决方案

OAuthException

如果不存在子代码,则意味着登录状态或访问口令已过期、被撤销或无效。获取新访问口令

如果存在子代码,请查看子代码。

102

API 会话

如果不存在子代码,则意味着登录状态或访问口令已过期、被撤销或无效。获取新访问口令

如果存在子代码,请查看子代码。

1

API 未知

可能是停机导致的临时问题。等待并重试操作。如果问题再次出现,请检查您是否在请求现有 API。

2

API 服务

停机导致的临时问题。等待并重试操作。

4

API 调用过多

节流导致的临时问题。等待并重试操作,或检查 API 请求量。

17

API 用户调用过多

节流导致的临时问题。等待并重试操作,或检查 API 请求量。

10

API 权限被拒绝

未授予权限或权限已被删除。处理缺失的权限

190

访问口令已过期

获取新访问口令

200-299

API 权限(多个值,取决于权限)

未授予权限或权限已被删除。处理缺失的权限

341

达到应用程序上限

停机或节流导致的临时问题。等待并重试操作,或检查 API 请求量。

368

因违反政策被暂时禁用

等待并重试操作。

506

重复帖子

不能连续发布重复的帖子。更改帖子内容并重试。

1609005

发布链接错误

从提供的链接中搜刮数据时出错。检查网址并重试。

身份验证错误子代码

代码 名称 解决方案

458

应用未安装

用户尚未登录应用。重新验证用户身份。

459

用户抽点检查

用户需要登录 https://www.facebook.com 或 https://m.facebook.com 纠正问题。

460

密码已更改

在 iOS 6 或版本更高的操作系统中,如果用户使用集成操作系统的流程登录,应将他们定向至设备上的 Facebook 操作系统设置,才能更新密码。否则,他们必须重新登录应用。

463

已过期

登录状态或访问口令已过期、被撤销或无效。处理过期的访问口令

464

用户未确认

用户需要登录 https://www.facebook.com 或 https://m.facebook.com 纠正问题。

467

访问口令无效

访问口令已过期、被撤销或无效。处理过期的访问口令

复杂参数

大部分参数类型都简单直接,如 stringint,但也有 listobject 类型,这些类型的参数也可以在请求中指定。

list 类型使用 JSON 语法指定,如:["firstitem", "seconditem", "thirditem"]

object 类型也使用 JSON 语法指定,如:{"firstkey": "firstvalue", "secondKey": 123}

调试 API 请求

图谱 API 调试模式

启用调试模式时,图谱 API 响应可能包含其他字段,说明请求可能存在的问题。

要启用调试模式,请使用 debug 查询字符串参数。例如:

GET graph.facebook.com
  /v2.3/me/friends
    access_token=...&
    debug=all

如果未授予 user_friends 权限,将生成以下响应:

{
  "data": [
  ], 
  "__debug__": {
    "messages": [
      {
        "message": "Field friends is only accessible on User object, if user_friends permission is granted by the user", 
        "type": "warning"
      }, 
      {
        "link": "https://developers.facebook.com/docs/apps/changelog#v2_0", 
        "message": "Only friends who have installed the app are returned in versions greater or equal to v2.0.", 
        "type": "info"
      }
    ]
  }
}

debug 参数值可以设置为“all”,也可以设置为与消息的 type 相对应的所请求的最低严重级别:

调试参数值 将返回的内容

all

所有可用的调试消息。

info

类型为 infowarning 的调试消息。

warning

仅类型为 warning 的调试消息。

调试信息(如可用)在 __debug__ 数组中的 messages 键下作为 JSON 对象返回。该数组的每个元素都是包含以下字段的 JSON 对象:

字段 数据类型 说明

message

字符串

消息内容。

type

字符串

消息严重性。

link

字符串

[可选]指向相关信息的网址。

您也可以配合图谱 API 探索工具使用调试模式。

确定 API 请求使用的版本

构建应用和发出图谱 API 请求时,您可能会发现,能够确定发出响应的 API 版本非常有用。例如,如果您执行调用但未指定版本,可能不知道进行响应的 API 版本。

图谱 API 为所有响应提供名为 facebook-api-version 的请求标头,说明生成响应的 API 的准确版本。例如,使用 2.0 版生成请求的图谱 API 调用具有以下 HTTP 标头:

facebook-api-version:v2.0

facebook-api-version 标头可帮助您确定 API 调用是否是从您期望的版本返回。

用于报告缺陷的调试信息

如果您需要报告图谱 API 中的缺陷,应将我们提供的一些其他请求标头随缺陷报告一同发送,以便帮助我们确定和重现问题。这些请求标头是 X-FB-Debugx-fb-revX-FB-Trace-ID