グラフAPIの利用

グラフAPIの基本的な用語と構造については、「グラフAPIの概要」で確認してください。このドキュメントでは、グラフAPIで実行できるさまざまな操作について詳しく説明します。

HTTP/1.1

すべてのデータ転送はHTTP/1.1に準じます。またすべてのエンドポイントはHTTPSが必要です。facebook.comincludeSubdomains HSTS指令も有効化されていますが、グラフAPIコールに悪影響がないようにする必要があります。

ホストURL

ほぼすべてのリクエストは、graph.facebook.comホストURLに渡されます。ただし、動画をアップロードする場合のみgraph-video.facebook.comを使います。

アクセストークン

アクセストークンにより、アプリはグラフAPIにアクセスできます。アクセストークンは通常、次のような2つの働きをします。

  • ユーザーのパスワードがなくても、アプリがユーザーの情報にアクセスできるようにする。
  • アプリ、アプリを使用しているユーザー、ユーザーがアプリにアクセスを許可したデータの種類を特定できるようにする。

すべてのグラフAPIエンドポイントには、何らかのアクセストークンが必要であるため、エンドポイントにアクセスするたび、リクエストにアクセストークンを含める必要があります。

トークンの仕組み

アクセストークンはOAuth 2.0プロトコルに準じています。OAuth 2.0により、ユーザーまたはページといったエンティティはトークンを許可できるようになります。通常、許可はウェブインターフェイスを通じて行われます。いったん許可されると、アプリはこれらのトークンを使用して特定の情報にアクセスできます。

例えば、このアプリはユーザーの写真、動画、メールアドレスへのアクセス許可をユーザーに求めています。

ご覧のとおり、これはFacebookのインターフェイスです。ユーザーは今、インターフェイスを通じて自分のアカウントにサインインしました。これによりユーザーを認証できます。ユーザーが操作を進めると、古いトークン(アプリトークン)が新しいトークン(ユーザートークン)と交換されます。アプリは新しいユーザートークンを使用してグラフAPIリクエストを行うことができます。ただし、アクセスできるのは特定のユーザーの写真、動画、メールアドレスのみです。

これはアクセストークンの重要な特性です。アプリIDとユーザーIDは、いずれもトークン自体で(他の情報とともに)エンコードされます。これらのIDを利用して、ユーザーがアプリにどのデータへのアクセスを許可したかをトラッキングします。例えば、ユーザーがアクセスを許可した後にトークンを調べると、次のような情報が明らかになります。

トークンはユーザーのデータへのアクセスを許可し、誰でも利用できる、非常に役に立つ存在です。だからこそクエリで使用するときには注意が必要です。そのための一番簡単な方法は、Facebookログインを利用したトークンの処理です。

Facebookログイン

OAuth 2.0では、リダイレクト、ログインプロンプト、トークンのやり取りが多くなるため、それらをもっと容易にするために Facebookログイン製品が開発されました。Facebookログインは、FacebookのすべてのSDKに対応した使いやすい機能とメソッドを採用しており、独自にソリューションを構築するよりもはるかに簡単なアクセストークン処理を可能にします。

アクセストークンやFacebookログイン、独自のソリューションの構築方法について詳しくは、「Facebookログインドキュメント」をご覧ください。

読み取り

ノード

読み取り操作は、通常ノードから始まります。ノードとは、一意のIDを持つ個別のオブジェクトです。ページノードオブジェクトは多数存在し、それぞれが一意のIDを持ちます。例えばコカ・コーラのページはIDが820882001277849である1つのみとなります。ノードを読み取るには、特定のオブジェクトのIDをクエリします。したがって、コカ・コーラのページのノードを読み取る場合は、前述のIDをクエリすることになります。

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

このリクエストにより、デフォルトでJSON形式のフィールド(ノードプロパティ)が次のように返されます。

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

エッジ

ノードはエッジを持ちます。エッジは通常、それらに割り当てられた他のノードのコレクションを返すことができます。エッジを読み取るには、ノードIDとエッジ名の両方をパスに含める必要があります。例えば、/pageノードの/feedエッジはページのすべての投稿ノードを返すことができます。エッジを使用してコカ・コーラのページのすべての投稿を取得する方法を次に示します。

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

応答にはコレクション内の投稿ノードのIDだけでなく、created_timeフィールドやmessageフィールドも含まれている点に注目してください。これは一般的なことです。ほとんどのエッジは、デフォルトで1つまたは複数のフィールドを含みます。

フィールド

フィールドはノードプロパティです。ノードをクエリすると、上述の例のように、デフォルトでフィールドのセットが返されます。ただし、fieldsパラメーターを使用すれば、返すフィールドを列挙して指定することもできます。これによりデフォルトが無効化され、返されるのは指定したフィールドとオブジェクトのID (IDは常に返されます)のみとなります。

例えば、ページノードリファレンスを見れば、ページノードを読み取るときに指定できるフィールドがわかります。コカ・コーラのページで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エッジを使用したとします。

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エッジが写真ノードIDのコレクションと、各写真のcreated_timeプロパティを返します。ノードと同様、fieldsパラメーターの使用により、コレクション内の各オブジェクトに対して返されるフィールドを指定できます。

例えば、/photosエッジによって返される各写真ノードに対して、heightwidthlink (URL)フィールドを取得するとします。

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パラメーターを使用してエッジを指定することもできます。これはフィールド拡張機能を使用しているときに便利です。

フィールド拡張機能

グラフAPIエクスプローラーで上記のGET /page/photosクエリをテストすると、リクエストが3つ以上のオブジェクトを返していること、また結果にページネーションが適用されていることに気付くでしょう。このことは、ほとんどのエッジで共通しています。結果の移動についてはこの後説明し、ここではフィールド拡張機能に焦点を絞ります。この機能は、クエリのネストの実行だけでなく、結果の制限並び替えも可能にします。

結果の制限

ページネーション結果の各セットで返されるオブジェクトの数を制限できます。結果を制限するには、フィールドまたはエッジに.limit()引数を追加します。

例えば、コカ・コーラのページの/feedエッジでGETリクエストを実行すると、何百もの投稿が返される場合があります。次のようにすれば、結果の各ページに対して返される投稿の数を制限できます。

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

これはコカ・コーラのページにある投稿のすべてを返しますが、各結果ページのオブジェクト数を3つに制限しています。フィードエッジをパスURL (/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"
}

ご覧のとおり、このページネーション結果ページには3つのオブジェクトのみが表示されていますが、応答にはnextフィールドとURLが含まれています。このURLを使用して次のページを取得できます。

結果の並び替え

オブジェクトの作成日時に基づいて、結果を並び替えることができます。並び替えるには、フィールドまたはエッジ上で、次の値のいずれかと一緒に、.order()引数を使用します。

  • chronological — 作成日時が一番古いオブジェクトを先頭にして結果を並べます。
  • reverse_chronological — 作成日時が一番新しいオブジェクトを先頭にして結果を並べます。

例えば、コカ・コーラのページの動画投稿(1809938745705498)の1つに対するすべてのコメントを取得して、結果を時系列(古い順)に並べるとします。ページネーション結果当たりのオブジェクト数は3つに制限します。

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

エッジで引数を使用するには、fieldsパラメーターでエッジを指定する必要があります。ご覧のとおり、1つのフィールドまたはエッジ上で、引数.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を返します。これは通常、オブジェクトの公開先のIDと新しいID文字列の組み合わせです。

{
  "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リクエストを実行する際、1回の応答でそのリクエストの結果すべてを受信するわけではありません。これは、応答によっては数千のオブジェクトが含まれている場合があり、デフォルトでは大半の応答にページネーションが適用されるためです。

カーソルベースのページネーション

カーソルベースのページネーションは、最も効率的なページング方法であり、可能な限り常に使用することをおすすめします。カーソルは、データのリスト内の特定のアイテムをマークする、ランダムな文字列を参照します。このアイテムが削除されない限り、カーソルは常にリスト内の同じ位置を指します。アイテムが削除されるとこの機能は無効になります。このため、アプリではカーソルを保管したり、それらのカーソルが将来にわたって有効であると想定したりしないようにしてください。

カーソルページネーションをサポートするエッジを読み取る際、以下の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個の場合、利用できるデータがまだあるとも考えられますが、プライバシーフィルターによって項目が1つ削除されています。 パフォーマンス上の理由により、一部のエッジでは、limit値が上限を超えて設定されることがあります。すべての呼び出しで、APIから正しいページネーションリンクが返されます。
  • next :データの次ページを返すGraphAPIエンドポイントです。含まれていない場合、これはデータの最終ページになります。ページネーションが可視性やプライバシーとどのように機能するかによって、ページが空になることもありますが、'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個の場合、利用できるデータがまだあるとも考えられますが、プライバシーフィルターによって項目が1つ削除されています。 パフォーマンス上の理由により、一部のエッジでは、limit値が上限を超えて設定されることがあります。すべての呼び出しで、APIから正しいページネーションリンクが返されます。
  • next :データの次ページを返すGraphAPIエンドポイントです。
  • previous :データの前のページを返すグラフAPIエンドポイントです。

一貫性のある結果を得るには、sinceパラメーターとuntilパラメーターの両方を指定します。また、時差は最大6か月とすることをおすすめします。

オフセットベースのページネーション

オフセットページネーションは、時系列についてはこだわらず、返された特定のオブジェクト数のみが必要な場合に利用できます。これは、エッジでカーソルベースや時間ベースのページネーションがサポートされていない場合にのみ、使うようにしてください。

オフセットページネーションエッジでは、以下のパラメーターがサポートされています。

  • offset :各ページの開始を指定した数だけずらします。
  • limit :返される可能性があるオブジェクトの最大数です。フィルタリング処理されるため、返されるクエリの数はlimitよりも少なくなる場合があります。データのリストの末尾に達したクエリを示す場合は、limitの値よりも小さな結果の数を使用するのではなく、下に示すように、nextがないことで示すようにしてください。例えば、limitを10に設定し、返された結果が9個の場合、利用できるデータがまだあるとも考えられますが、プライバシーフィルターによって項目が1つ削除されています。 パフォーマンス上の理由により、一部のエッジでは、limit値が上限を超えて設定されることがあります。すべての呼び出しで、APIから正しいページネーションリンクが返されます。
  • next :データの次ページを返すGraphAPIエンドポイントです。含まれていない場合、これはデータの最終ページになります。ページネーションが可視性やプライバシーとどのように機能するかによって、ページが空になることもありますが、'next'ページングリンクは含まれています。'next'リンクが表示されない場合は、ページングを停止してください。
  • previous :データの前のページを返すグラフAPIエンドポイントです。含まれていない場合、これはデータの最初のページになります。

ページネーションされるアイテムリストに新しいオブジェクトが追加されると、各オフセットベースページのコンテンツが変わります。

オフセットベースのページネーションは、API呼び出しではサポートされていません。一貫した結果を得るには、応答で返されたpreviousリンクやnextリンクを使ってページネーションすることをおすすめします。