Facebook APIリクエストを高速化する新しい5つの方法

昨秋、Habréに投稿を公開しました。実際にFacebook APIリクエストを高速化する5つの方法で 、これは優れたレシピ集であることが判明しました。 この間、Facebook APIは大きく変化し、さらに良くなりました。 現在、APIへの1つのHTTP要求で処理できなかったタスクはほとんど見られません。 そして、これからお話しする新機能のおかげです。



画像



前回の方法は次のとおりです。

  1. 必要なフィールドのみをリクエストします

    me?fields = id、name、birthday
  2. 1つのリクエストで複数のオブジェクトのデータをリクエストします

    ?ids = 4,501012028
  3. フィルタリングとページネーションを使用します

    私/友達?limit = 10&offset = 10
  4. FQLクエリの使用

    fql?q = SELECT uid、name、birthday_date FROM FROMユーザーWHERE uid IN(SELECT uid2 FROM friend WHERE uid1 = me())
  5. 複数のリクエストを含むバッチリクエストを送信します

    batch = [{"method": "GET"、 "relative_url": "me"}、{"method": "GET"、 "relative_url": "me / friends?limit = 50"}]




すべてのクエリは、FAPIクエリをサポートするGraph API Explorerで実行できます。



1)マルチクエリ



マルチクエリは、単一のGraph APIクエリで送信される複数のFQLクエリです。 複数クエリは、バッチリクエストを介して送信されるFQLクエリの同じパックよりも高速に処理されます。 同時に、複数のオブジェクトに答えを渡すだけでなく、単純なFQLクエリの問題の1つを解決することもできます。



特定のイベントに参加するユーザーのリストを取得するとします。 FQLクエリを記述します。

SELECT name、url、pic FROMプロファイルWHERE id IN(SELECT uid FROM event_member WHERE eid = 12345678)



ただし、このようなリクエストは、ステータス情報(出席、不確か、拒否、not_replied)を提供せずにすべてのユーザーに提供します。 イベントに参加する人だけに情報を表示する必要がある場合は、すべてうまくいきます。 次に、 サブクエリの条件にAND rsvp_status = 'attending'を追加するだけです。 しかし、すべてのユーザーを1ページに表示する必要があり、RSVPステータスでそれらを壊す場合はどうすればよいでしょうか。 異なる条件で4つのFQLクエリを実行し、バッチを使用して送信しますか?



Facebookでは、2つのリクエストを行い、2番目のリクエストを使用するように提案しています。 この例では、クエリは次のようになります。

「Query1」:「SELECT uid、rsvp_status FROM event_member WHERE eid = 12345678」

「Query2」:「SELECT name、url、pic FROMプロファイルWHERE id IN(SELECT uid FROM#query1)」

これで、1回のリクエストで必要なすべてのデータを受け取ることができ、バッチを使用するよりも高速になります。



マルチクエリの詳細については、 ドキュメントをご覧ください。



2)複数のメソッドと操作間の依存関係を含むバッチ要求



これで、1つのバッチリクエストで、GET、POST、DELETEなどの異なるHTTPメソッドを渡すことができます。 たとえば、新しいステータスを公開し、ユーザーのフィードを1つのリクエストで返します。 しかし、パンはこれではなく、「依存関係」にあります。



最初は、リクエストは独立していました。 ただし、 JSONPath式を使用して依存関係を管理しながら、あるクエリのデータを別のクエリで使用できるようになりました。



最も簡単な例:5人の友人のデータを取得します。 これは、次のクエリを使用して実行できます。

batch = [{"method": "GET"、 "name": "get-friends"、 "relative_url": "me / friends?limit = 5"、}、{"method": "GET"、 "relative_url" : "?ids = {result = get-friends:$。data。*。id}"}]



やめて! したがって、Multi-queryを使用して同じことができます、とあなたは言います。 はい、すべての力を示すために別の例を選択する必要があります。 そして、どのようにこれが好きですか:

batch = [{"method": "GET"、 "name": "one-friend"、 "relative_url": "me / friends?limit = 1"、}、{"method": "POST"、 "relative_url" :「Me / feed」、「body」:「message = {result = one-friend:$。Data.0.name} is my friend」}]

ユーザーの友人の1人を取得し、彼のデータを使用して新しい投稿を公開します。 2つの個別のクエリは必要ありません。



バッチで最大50のリクエストを使用し、emit_response_on_successおよびdepend_onパラメーターを使用してリクエストの動作を制御し、異なるリクエストで異なるaccess_token(ユーザー、ページ、アプリケーション)を使用することもできます。 バッチリクエストのドキュメント。



3)ETag



年の初めに、FacebookはHTTP ETagsをサポートしました 。 彼らの仕事の原理は簡単です:

  1. Graph APIリクエストを実行すると、レスポンスは、APIを介して返されたデータのハッシュ値であるETagヘッダーを返します。
  2. 次回同じリクエストを呼び出すときに、ステップ1で取得したデータとともにIf-None-Matchヘッダーを渡します。
  3. データが変更されていない場合、応答としてデータなしで304-Not Modifiedを受け取ります。
  4. データが変更された場合、データは通常どおり返されます(ポイント1)。


頻繁に変更されないデータでこれを使用することをお勧めします。 たとえば、フィードや投稿リクエストでETagを使用しないでください。 ただし、接続速度の遅いモバイルアプリでの友達リクエストの場合、パフォーマンスは確実に向上します。



開発者ブログのこの投稿で、ETagとサンプルコードの詳細を読むことができます。



4)フィールド拡張



上記で、マルチクエリとJSONPathを使用したバッチを使用して、1つのクエリで関連オブジェクトからデータを取得する2つの方法を既に説明しました。 ただし、リクエストのグラフAPIには、より簡単なオプションがあります。



たとえば、ページにユーザーの名前、誕生日、最後の10枚の写真を表示します。 このクエリを使用して、これをすべて実行できます。

me?fields = name、birthday、photos.limit(10).fields(id、picture)



または、写真にコメントを表示したいが、標準のフィールドでは不十分であり、別のコメンテーターの誕生日を追加したい。 要求は次のとおりです。

<photo_id> /comments?fields=from.fields(id、name、birthday)



すべての識別子、フィールド、接続に対してこのようなリクエストを行うことができます。 ずっと簡単で便利ではないですか? フィールド拡張ドキュメント。



5)ページネーション



前の記事で、フィルターとオフセットを使用したフィルター処理とページネーションについて既に書いています。 この方法は非常に便利ですが、大きな欠点が1つあります。 各リクエストでは、その背後にあるデータが存在するかどうかに関係なく、前のリンクと次のリンクが表示されます。



Facebookは、カーソルベースのオフセットページングという新しいソリューションを提供しています。 データがもうない場合、前と次が表示されなくなります。 前/次のページがある場合、リクエスト内の前/後のリンクが表示されます。 オブジェクトの各コレクションを調べることにより、「1パス」を保存します。



残念ながら、カーソルベースのページネーションはまだすべてのオブジェクトで利用できるわけではありません。 しかし、これは時間の問題です。 ドキュメントに従って、より効果的なソリューションを使用してください。



最適化の機会をすべて使用した場合は、記事「 リアルタイム更新を使用したFacebook Graph APIへのリクエストの最適化」を必ずご覧ください。



結論として、モスクワでは10月1日にFacebook Developer HACK 2012が開催されることを思い出したいと思います。直接参加できない場合は、コメントに質問を残してください。 個人的に、私はFacebookのエンジニアに十分な質問を蓄積しました。



All Articles