使用 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 登入,或瞭解如何建立自己的解決方案,請參閱 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 調用都支援位移型分頁。若要取得一致的結果,我們建議您使用在回應中傳回的上一頁/下一頁連結來分頁。