使用 Graph API

在我們的 Graph API 概覽中,說明 Graph API 的專用術語和結構基本入門。本文件將詳述更多有關使用 Graph API 執行各項操作的細節。

HTTP/1.1

所有的資料傳輸都會遵守 HTTP/1.1,且所有端點都需要使用 HTTPS。我們也啟用了 facebook.comincludeSubdomains HSTS 指令,但這不會對您的 Graph API 調用造成負面影響。

代管網址

幾乎所有的要求都會傳送到 graph.facebook.com 代管網址。唯一的例外是影片上載,會改用 graph-video.facebook.com

存取憑證

存取憑證可以讓您的應用程式存取 Graph API。存取憑證通常可執行兩種功能:

  • 讓您的應用程式在不需要用戶密碼的情況下,存取用戶資訊,並
  • 讓我們辨識您的應用程式、應用程式用戶,以及用戶允許您的應用程式存取的資料類型。

所有的 Graph API 端點都需要使用某種存取憑證,所以當您每次存取端點時,要求內都一定要包含存取憑證。

憑證運作方式

存取憑證會遵守 OAuth 2.0 通訊協定。OAuth 2.0 可讓實體(如用戶或專頁)授權憑證。通常這是透過網路介面辦到。成功授權後,應用程式可使用這些憑證來存取特定資訊。

舉例來說,這個應用程式正在要求用戶授予權限,以存取用戶的相片、影片與電郵地址:

如您所見,這是個 Facebook 介面。用戶剛利用這個介面登入他們的帳戶,這讓我們可以驗證該用戶。如果用戶持續操作,我們就會以舊的憑證(應用程式憑證)交換新的憑證(用戶憑證)。然後應用程式就能使用新的用戶憑證傳送 Graph API 要求,但只能存取該特定用戶的相片、影片與電郵地址。

這是存取憑證的重要屬性。應用程式和用戶編號(以及其他內容)都已編碼至憑證中,我們會使用這些編號來追蹤用戶允許應用程式存取哪些數據類型。舉例來說,如果您在用戶授權後檢查憑證,就會看到以下資訊:

由於憑證允許應用程式存取用戶資料,而且任何人都可以使用憑證,這些憑證非常重要,因此於查詢中使用憑證時請務必格外謹慎。如要做到這一點,最簡單的方式就是使用 Facebook 登入功能來處理憑證。

Facebook 登入

OAuth 2.0 中含有許多重新導向、登入提示與憑證交換,所以為了簡化操作,我們創造了 Facebook 登入產品。Facebook 登入功能擁有適用於我們所有的 SDK 而且簡單易用的函數與方法,能讓您更輕鬆地使用存取憑證,而且您無需自行建立解決方案。

若要進一步瞭解存取憑證與 Facebook 登入功能,或瞭解如何建立自己的解決方案,請參閱 Facebook 登入文件

讀取

節點

讀取操作幾乎固定是從節點開始。節點是一個含有不重複編號的個別物件。舉例來說,有許多專頁節點物件各自擁有不重複的編號,例如 Coca-Cola 專頁是唯一擁有編號 820882001277849 的專頁。若要讀取節點,您可以查詢特定物件的編號。所以若要讀取 Coca-Cola 專頁節點,您可查詢其編號:

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

根據預設,此要求會按照 JSON 格式傳回下列欄位(節點屬性):

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

邊緣

節點有邊緣,邊緣通常可以回傳附加在其上的其他節點組合。若要讀取邊緣,您必須在路徑中加入節點編號與邊緣名稱。舉例來說,/page 節點必須有 /feed 邊緣,後者可傳回專頁的所有帖子節點。以下是使用邊緣取得 Coca-Cola 專頁的所有帖子的方法:

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

JSON 回應看起來如同這樣:

{
  "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"
    }
  ]
}

請注意,回應不只會包含組合中的帖子節點編號,同時也會有 created_timemessage 欄位。這很正常。根據預設,大部分的邊緣會包含一個或多個欄位。

欄位

欄位是節點屬性。當您查詢節點,系統預設會傳回一組欄位,如上方範例所示。但您也可以使用 fields 參數並列出各個欄位,以指定您要傳回的欄位。這樣就能覆寫預設設定,使系統只傳回您指定的欄位及物件編號,後者為必定傳回的資料。

舉例來說,專頁節點參考資料已列出您在讀取專頁節點時可要求哪些欄位。如果您想取得 Coca-Cola 專頁的 aboutfan_countwebsite 欄位,您可以執行以下動作:

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

此舉將傳回下列回應:

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

邊緣通常會傳回一組物件,另外也會傳回組合中每個物件的欄位。假設您使用 /photos 邊緣取得 Coca-Cola 專頁的所有相片節點:

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

此舉產生的回應就會類似這樣:

{
  "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"
    }
  ]
}

如您所見,根據預設,/photos 邊緣會傳回一組相片節點編號,以及每張相片的 created_time 屬性。與節點一樣,您可以使用 fields 參數來指定組合中每個傳回物件要傳回的特定欄位。

假設您要取得 /photos 邊緣傳回的每個相片節點的 heightwidthlink(網址)欄位:

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

回應如下所示:

{
  "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"
    }
  ]
}

請注意,您亦可使用 fields 參數來指定邊緣,這在您使用欄位擴充功能時將會十分實用。

欄位擴充

在 Graph API 測試工具中測試上列的 GET /page/photos 查詢時,您也許會注意到要求傳回的物件超過三個,而且結果還會分頁。這對大多數的邊緣來說都正常情況。我們接下來會講解有關瀏覽分頁結果的資訊,但現在先讓我們來看看欄位擴充;此功能不只可讓您執行巢狀要求,還能限制排序結果。

限制結果

限制功能可讓您控制每組分頁結果所傳回的物件數量。若要限制結果,請將 .limit() 引數加入任何欄位或邊緣。

舉例來說,若在 Coca-Cola 專頁的 /feed 邊緣上執行 GET 要求,系統或會傳回幾百則帖子。您可以限制每頁結果傳回的帖子數量,執行方式如下:

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

這會傳回 Coca-Cola 專頁上的所有帖子,但每頁結果的物件數量上限將會設為三個。請注意,您並非指定路徑網址 (/page/feed) 的動態邊緣,而是在 fields 參數 (?fields=feed) 中指定它,後者可讓您附加 .limit(3) 引數。

此為查詢結果:

{
  "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"
}

如您所見,這個分頁結果的頁面中只有三個物件,但回應中包含 next 欄位與網址,讓您用來擷取下一頁。

排序結果

您可以根據物件的建立時間來排序結果。若要這樣做,請在欄位或邊緣上使用 .order() 引數及下列其中一個值。

  • chronological — 由最早建立的物件開始排序結果。
  • reverse_chronological — 以最遲建立的物件開始排序結果。

舉例來說,假設我們要取得 Coca-Cola 專頁其中一個影片帖子 (1809938745705498) 的所有回應,按照時間順序排序結果(從最舊到最新),並將分頁結果的物件數量上限設為三個:

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

正如上文所述,如果您想在邊緣使用引數,就必須在 fields 參數中指定邊緣。如您所見,您可以在單一欄位或邊緣上結合 .limit().order() 引數。

結果如下:

{
  "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"
}

發佈

大部分的邊緣都能讓您發佈物件至節點的物件組合。您可以在節點的邊緣上使用 POST 要求來操作。例如,您可以使用相片節點的 /comments 邊緣,在相片上發佈回應:

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

成功的話,大多數的邊緣都會傳回您剛剛發佈的物件編號,這通常會是發佈物件編號與新編號字串的組合:

{
  "id": "1809938745705498_1810399758992730"
}

發佈功能通常需要其他的權限,所以請參考每個邊緣的參考資料文件,以瞭解所需權限。

用來發佈物件的存取憑證可能會影響物件的外觀。若是使用專頁存取憑證,看起來就如同是專頁發佈了該物件;若使用用戶存取憑證,看起來就如同是用戶發佈了該物件。

許多邊緣也支援進階功能,例如先寫後讀可讓您立即讀取新發佈的物件,而批次發佈則可讓您同時執行多個發佈操作。

更新

您可以使用 POST 要求,在現有的節點上執行更新操作。例如,若要更新現有回應的 message 欄位,您可以執行以下動作:

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

成功的話,節點就會傳回 success 欄位與 true 的值:

{
  "success": true
}

與發佈操作一樣,更新操作也需要使用其他的權限,詳情請參閱個別節點的參考資料文件。另外,與大多數的邊緣相同,許多節點也會支援先寫後讀功能。

刪除

您通常可以使用 DELETE 操作來刪除節點:

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

成功的話,節點就會傳回 success 欄位與 true 的值:

{
  "success": true
}

一般來說,您只能刪除自己建立的節點,但您也可以參閱每個節點的參考資料指南,以瞭解刪除操作的具體條件。

若要支援尚未支援所有 HTTP 方法的用戶端,您可以傳送 POST 要求至節點,並加入 method=delete 參數與值以覆寫 HTTP 方法:

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

瀏覽分頁結果

當您對節點或邊緣發出 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:會傳回資料下一頁的 Graph API 端點。如果未包含這個修飾詞,就會傳回資料的最後一頁。基於分頁利用能見度和私隱設定的方式,有可能某頁為空,但包含「下一頁」的分頁連結。當「下一頁」連結不再出現時,請停止分頁。
  • previous:會傳回資料上一頁的 Graph 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:會傳回資料下一頁的 Graph API 端點。
  • previous:會傳回資料上一頁的 Graph API 端點。

為求結果保持一致,請指定 sinceuntil 參數。此外,我們建議時差的上限不要超過 6 個月。

位移型分頁

當您不在乎時間順序,而只想要傳回特定數目的物件時,可使用位移分頁。僅當邊緣不支援游標或時間型分頁時,才應該使用位移分頁。

位移分頁的邊緣支援以下參數:

  • offset:根據指定數字位移每一頁的開頭。
  • limit:這是系統可能會傳回的物件數量上限。因為經過篩選的關係,查詢傳回的物件數量可能會少於 limit 的數值。請勿以查詢結果數量少於 limit 的數值來判斷查詢是否已達到資料清單的盡頭,並改用 next 存在與否來判斷(詳情請參見下文)。舉例來說,如果您將 limit 設定為 10,而系統傳回了 9 個查詢結果,則有可能還有更多資料,但是其中一個項目因為私隱篩選條件而被移除。基於效能因素,某些邊緣的 limit 數值也設有上限。在所有的情況下,API 都會傳回正確的分頁連結。
  • next:會傳回資料下一頁的 Graph API 端點。如果未包含這個修飾詞,就會傳回資料的最後一頁。基於分頁利用能見度和私隱設定的方式,有可能某頁為空,但包含「下一頁」的分頁連結。當「下一頁」連結不再出現時,請停止分頁。
  • previous:會傳回資料上一頁的 Graph API 端點。如果未包含這個修飾詞,就會傳回資料的第一頁。

請注意,如果已將新的物件加入分頁中項目清單,每個位移型分頁的內容將會變更。

並非所有 API 調用都支援位移型分頁。若要取得一致的結果,我們建議您使用我們在回應中傳回的上一頁/下一頁連結來分頁。

若是傳回項目數量很大的物件,例如數以萬計的 [評論](文件/Graph API/參考文件/物件/評論),您可能會在分頁時遇到限制。如果您的應用程式達到了游標限制,API 會傳回錯誤訊息:

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