JavaScript クライアント ライブラリ(v2.0)を使用する

警告: このページは、Google の古い API である Google Data API を対象としています。Google Data API ディレクトリに記載されている API のみを対象としており、その多くは新しい API に置き換えられています。特定の新しい API については、その新しい API のドキュメントをご覧ください。新しい API を使用してリクエストを承認する方法については、Google アカウントの認証と承認をご覧ください。

このドキュメントでは、JavaScript クライアント ライブラリを使用して Google Data API クエリを送信し、返されたレスポンスを解釈する方法について説明します。

Google は、データ API を持つサービスを操作するための、さまざまなプログラミング言語によるクライアント ライブラリのセットを提供しています。これらのライブラリを使用すると、API リクエストを作成してサービスに送信し、レスポンスを受け取ることができます。

このドキュメントでは、JavaScript クライアント ライブラリの使用に関する一般情報と、一般的な使用例を紹介します。

対象者

このドキュメントは、Google データサービスとやり取りできるクライアント アプリケーションを作成する JavaScript プログラマーを対象としています。

このドキュメントは、Google Data API プロトコルの背後にある一般的な概念を理解していることを前提としています。また、JavaScript でのプログラミング方法を理解していることを前提としています。

クライアント ライブラリで提供されるクラスとメソッドのリファレンス情報については、JavaScript クライアント ライブラリの API リファレンス(JSdoc 形式)をご覧ください。

このドキュメントは順番に読むことを目的としています。各例は前の例に基づいています。

利用規約

JavaScript クライアント ライブラリを使用するときは、Google JavaScript クライアント ライブラリの利用規約に同意したものとみなされます。

データモデルと制御フローの概要

JavaScript クライアント ライブラリは、Google Data API で使用される要素を表す一連のクラスを使用します。

: データの基盤となる表現は JSON ですが、クライアント ライブラリには抽象化レイヤが用意されているため、JSON データを直接操作する必要はありません。クライアント ライブラリを使用せずに JSON を直接操作する場合は、Google Data API での JSON の使用をご覧ください。

このライブラリには、Data API を備えたサービスとの間でデータを非同期的に送受信するメソッドが用意されています。たとえば、google.gdata.calendar.CalendarService.getEventsFeed() メソッドは Google カレンダーにフィードのリクエストを送信します。渡すパラメータの 1 つに継続関数(コールバック)があります。サービスは、継続関数を呼び出してフィードを JSON 形式で返します。クライアントはさまざまな get メソッドを呼び出して、JavaScript オブジェクトの形式でデータを使用できます。

新しいエントリを追加するには、クライアント ライブラリのクラスとメソッドを使用してエントリを作成し、feed.insertEntry() メソッドを呼び出して新しいエントリをサービスに送信します。再度、継続関数を指定します。この関数は、エントリが正常に追加されたときにサービスを呼び出します。

JavaScript を初めて使用する場合は、制御フローが少しわかりづらいかもしれません。getEventsFeed()insertEntry() などのメソッドを呼び出すと、ほとんどの場合、スクリプトは終了します。サービスが要求されたデータを返すと、継続関数内で実行が再開される。したがって、返されたデータに対してクライアントが行うことはすべて、継続関数で実行するか、その関数から呼び出す必要があります。複数の関数で使用するために一部の変数をグローバル化しなければならない場合があります。

このプログラミング スタイルについて詳しくは、Wikipedia の「Continuation-passing style」(英語)をご覧ください。

サポートされる環境について

現時点では、ブラウザのウェブページで実行される JavaScript クライアント アプリケーションのみに対応しています。現在サポートされているブラウザは次のとおりです。

  • Firefox 2.x と 3.x
  • Internet Explorer 6、7、8
  • Safari 3.x および 4.x
  • Google Chrome(すべてのバージョン)

JavaScript クライアント ライブラリは、サービスのサーバーとの通信をすべて処理します。経験豊富な JS デベロッパーであれば、「同じオリジン ポリシーはどうなるのだろう」と思われるかもしれません。JavaScript クライアント ライブラリを使用すると、ブラウザのセキュリティ モデルを維持しながら、あらゆるドメインから Google データ リクエストを送信できます。

Google Data API による認証の概要については、Google Data API の認証の概要をご覧ください。このドキュメントの残りの部分では、このシステムの基本的な仕組みを理解していることを前提としています。

サンプル クライアント アプリケーション

JavaScript クライアント ライブラリの実際の動作については、サンプルページをご覧ください。

チュートリアルと例

次の例は、JavaScript クライアント ライブラリを使用してさまざまなデータ API リクエストを送信する方法を示しています。

具体例として、特定のサービス(Google カレンダー)を利用する方法を説明します。Google カレンダーは、他の Google サービスと異なる点を示し、他のサービスで使用できるようにサンプルを調整します。カレンダーについて詳しくは、Google Calendar Data API のドキュメントをご覧ください。

ライブラリを読み込む

クライアントでクライアント ライブラリを使用するには、まずクライアント ライブラリ コードをサーバーにリクエストする必要があります。

まず、HTML ドキュメントの <head> セクションの <script> タグを使用して、Google AJAX API ローダを取得します。

<script type="text/javascript" src="https://www.google.com/jsapi"></script>

ライブラリをプリロードすることで、Google のサーバーへの往復を最小限に抑え、レイテンシを短縮できます。特定のパッケージを Google AJAX API ローダ(google.load()下記参照を除く)から直接プリロードするには、次のように記述します。

<script type="text/javascript"
      src="https://www.google.com/jsapi?autoload=%7Bmodules%3A%5B%7Bname%3Agdata%2Cversion%3A2.x%2Cpackages%3A%5Bblogger%2Ccontacts%5D%7D%5D%7D"></script>

: スクリプトの src URL は完全に URL エンコードする必要があります。たとえば、前の例は
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={modules:[{name:gdata,version:2.x,packages:[blogger,contacts]}]}"></script> です。

モジュールを自動読み込みしない場合は、JavaScript の設定コードで次の例を使用して、共通のローダを取得した後、Google データ クライアント ライブラリを読み込むことができます。この呼び出しは、HTML ドキュメントの <head> セクション、または、HTML ドキュメントの <head> セクションを指定する <script> タグを使用して設定された JavaScript ファイルから行う必要があります。

google.load("gdata", "2");

または、ライブラリ全体ではなく特定のサービスをリクエストすることもできます。この例では、Blogger と連絡先用のパッケージのみをダウンロードします。

google.load("gdata", "2.x", {packages: ["blogger", "contacts"]});

google.load() の 2 番目のパラメータは、リクエストされた JavaScript クライアント ライブラリのバージョン番号です。このバージョン番号体系は、Google Maps API が採用している方式をモデルとしています。表示されるバージョン番号とその意味は次のとおりです。

"1"
メジャー バージョン 1 の最後から 2 番目のリビジョン。
"1.x"
メジャー バージョン 1 の最新リビジョン。
"1.s"
メジャー バージョン 1 の最新の安定版。Google がデベロッパーから受け取るフィードバックに基づき、特定のバージョンのクライアント ライブラリを「安定版」として宣言することがあります。ただし、このバージョンには最新の機能が含まれていない場合があります。
"1.0""1.1」など
メジャー バージョンとマイナー リビジョン番号が指定された、ライブラリの特定のバージョン。

google.load() を呼び出したら、ローダに対して、ページの読み込みが完了するまで待機してからコードを呼び出すよう指示する必要があります。

google.setOnLoadCallback(getMyFeed);

ここで、getMyFeed() はこのドキュメントの次のセクションで定義する関数です。onload ハンドラを <body> 要素にアタッチするのではなく、このアプローチを使用します。

未認証フィードをリクエストする

未認証フィードをリクエストするには、JavaScript ファイル、または HTML ファイルの <script> タグに次のコードを追加します。

次のコードでは、(上記の getMyFeed() が AJAX API ローダによって先に)呼び出されます。

setupMyService() を呼び出して Google カレンダーへの接続(CalendarService オブジェクトで表されます)を作成します。サービス作成コードを、モジュール化のために別の関数に引き出しました。後で、認証の選択に応じて、setupMyService() 関数を変更します。

サービスの設定後、getMyFeed() はクライアント ライブラリの getEventsFeed() メソッドを呼び出してフィードをリクエストします。

後の関数で使用できるように、フィードの URL をグローバル変数で指定します。この例では、liz@gmail.com という名前のユーザーの公開(未認証)フィード URL を使用します。認証済みのユーザーを表すために、ユーザーのメールアドレスの代わりに default を使用することもできます。

var feedUrl = "http://www.google.com/calendar/feeds/liz@gmail.com/public/full";

function setupMyService() {
  var myService = new google.gdata.calendar.CalendarService('exampleCo-exampleApp-1');
  return myService;
}

function getMyFeed() {
  myService = setupMyService();

  myService.getEventsFeed(feedUrl, handleMyFeed, handleError);
}

後の関数で使いやすくするため、myService をグローバル変数にしています。

上記の手順を独自のクライアントで機能させるには、カレンダーを一般公開して共有するカレンダー アカウントに対して、実際のユーザーのメールアドレスを使用する必要があります。

: 新しい CalendarService オブジェクトを作成すると、クライアント ライブラリは google.gdata.client.init() という名前のメソッドを呼び出します。このメソッドは、クライアントが実行されているブラウザのサポート状況を確認します。エラーが発生すると、クライアント ライブラリにエラー メッセージが表示されます。このようなエラーを自分で処理する場合は、サービスを作成する前に google.gdata.client.init(handleInitError) を明示的に呼び出すことができます。ここで、handleInitError() は関数です。init エラーが発生した場合、関数は標準の Error オブジェクトを受け取ります。そのオブジェクトを使って何でもできます。

getEventsFeed() の呼び出しで、2 番目の引数は handleMyFeed です。これはコールバック関数です。以下をご覧ください。Google カレンダーはリクエストを処理し、リクエストが成功した場合は、リクエストされたフィードを含む「フィード ルート」オブジェクトをコールバックに渡します。フィードルートは、フィードを含むコンテナ オブジェクトです。

getEventsFeed() の 3 番目の引数は、オプションのエラー処理関数です。クライアント ライブラリでエラーが発生した場合、成功コールバック関数ではなく、指定されたエラーハンドラが呼び出されます。クライアント ライブラリが引数としてエラーハンドラに渡すオブジェクトは、JavaScript Error オブジェクトのインスタンスであり、cause プロパティが追加されています。

コールバック関数のシンプルなバージョンとエラーハンドラを次に示します。

function handleMyFeed(myResultsFeedRoot) {
  alert("This feed's title is: " + myResultsFeedRoot.feed.getTitle().getText());
}

function handleError(e) {
  alert("There was an error!");
  alert(e.cause ? e.cause.statusText : e.message);
}

エラーはユーザーに表示するだけで処理します。クライアントのエラーハンドラはより高度なものにします。状況が特定されないこともあります。その場合、エラーハンドラの例は標準の message プロパティにフォールバックします。

なお、このコードは認証を行わないため、公開フィードの取得にのみ使用できます。

認証中

JavaScript クライアント ライブラリは 2 つのモードで使用できます。ガジェットを作成する場合、認証には OAuth プロキシと呼ばれる機能を使用します。スタンドアロンの JavaScript アプリケーションからアクセスされる場合は、AuthSub 認証システムを使用します。 認証の詳細については、Google Data API の認証の概要をご覧ください。このセクションの残りの部分では、このシステムの基本的な仕組みについて理解していることを前提としています。

このドキュメントに記載されているサンプルコードで認証を使用する前に、フィードの URL を公開から非公開に変更します。

var feedUrl = "http://www.google.com/calendar/feeds/liz@gmail.com/private/full";

AuthSub を使用してウェブ クライアントで認証する

Google の「JavaScript 用 AuthSub」認証システムはご利用いただけなくなりました。

代わりに、クライアントサイド アプリケーションに OAuth 2.0 を使用することをおすすめします。

ガジェットで OAuth プロキシを使用して認証する

ガジェットの認証プロセスの概要は次のとおりです。

  1. ガジェットが初めて読み込まれ、いずれかの Google Data API を使用してユーザーのデータにアクセスを試みます。
  2. ユーザーがデータへのアクセスをまだ許可していないため、リクエストは失敗します。レスポンス オブジェクトには、OAuth 承認ページの URL(response.oauthApprovalUrl)が含まれます。ガジェットは、この URL で新しいウィンドウを起動するメソッドを提供する必要があります。
  3. 承認ページで、ユーザーはガジェットへのアクセスを許可または拒否します。成功すると、指定した oauth_callback ページがユーザーに表示されます。最良のユーザー エクスペリエンスを実現するには、http://oauth.gmodules.com/gadgets/oauthcallback を使用します。
  4. 次に、ユーザーはポップアップ ウィンドウを閉じます。ユーザーが承認した旨をガジェットに通知できるように、ポップアップ ハンドラが用意されています。これを使用して、承認ウィンドウの終了を検出できます。または、このウィンドウを閉じた後、ユーザーが手動でクリックできるリンク(「アクセスを承認した」など)を表示することもできます。
  5. ユーザーのデータを再度リクエストして、ガジェットが Google Data API へのアクセスを 2 回試みます。この試行は成功しました。
  6. ガジェットは認証され、正常に動作します。

ガジェットの <OAuth> 要素を <ModulePrefs> セクションに追加します。

<ModulePrefs>
...
<OAuth>
  <Service name="google">
    <Access url="https://www.google.com/accounts/OAuthGetAccessToken" method="GET" /> 
    <Request url="https://www.google.com/accounts/OAuthGetRequestToken?
                  scope=http://www.blogger.com/feeds/%20http://www.google.com/calendar/feeds/" method="GET" /> 
    <Authorization url="https://www.google.com/accounts/OAuthAuthorizeToken?
                        oauth_callback=http://oauth.gmodules.com/gadgets/oauthcallback" /> 
  </Service>
</OAuth>
...
</ModulePrefs>

このセクションでは、次のクエリ パラメータを変更します。

  • scope

    リクエスト URL の必須パラメータ。ガジェットでアクセスできるのは、このパラメータで使用されている scope のデータのみです。 この例では、ガジェットから Blogger とカレンダーのデータにアクセスできます。ガジェットは、この例のように 1 つまたは複数のスコープのデータをリクエストできます。

  • oauth_callback

    認証 URL の省略可能なパラメータ。ユーザーがデータへのアクセスを承認すると、OAuth 承認ページがこの URL にリダイレクトされます。 このパラメータを省略することも、独自の「承認済みページ」に設定することも、http://oauth.gmodules.com/gadgets/oauthcallback を使用することもできます。ユーザーが最初にガジェットをインストールしたときに、最良のユーザー エクスペリエンスが提供されます。このページには、ポップアップ ウィンドウを自動的に閉じる JavaScript スニペットがあります。

次に、ガジェットの <Content> セクションで JavaScript クライアント ライブラリを読み込みます。前の例の setupMyService() 関数を変更して、サービス オブジェクトの useOAuth() メソッドを呼び出します。これにより、ガジェットは AuthSub ではなく OAuth プロキシを使用して認証を行うようになります。以下のテンプレートからすぐに始められます。

<Content type="html">
<![CDATA[
  ...
  <script src="https://www.google.com/jsapi"></script>
  <script type="text/javascript">
    var myService = null;
    
    function setupMyService() {
      myService = new google.gdata.calendar.CalendarService('exampleCo-exampleApp-1');
      myService.useOAuth('google');
      fetchData();
    }
    
    function initGadget() {
      google.load('gdata', '2.x');
      google.setOnLoadCallback(setupMyService);
    }

    function fetchData() {            
      var callback = function(response) {
        if (response.oauthApprovalUrl) {
        
          // TODO: Display "Sign in" link (response.oauthApprovalUrl contains the URL) 
          
        } else if (response.feed) {
        
          // TODO: show results
          
        } else {
        
          // TODO: handle the error
          
        }
      };

      myService.getEventsFeed('http://www.google.com/calendar/feeds/default/public/full', callback, callback);
    }
    
    gadgets.util.registerOnLoadHandler(initGadget);
  </script>
  ...
]]> 
</Content>

google.accounts.user.login(scope) の呼び出しは削除されています。プロキシが認証を処理します。

fetchData() に含まれる内容など、Google Data API ガジェットの作成について詳しくは、Google データ ガジェットの作成に関する記事をご覧いただくか、OAuth ガジェットを作成するをご覧ください。

新しいアイテムを挿入する

新しいカレンダーの予定を作成するには、handleMyFeed() 関数の末尾を変更して新しい関数を呼び出すことにより、上記の例の実行を続行します。

function handleMyFeed(myResultsFeedRoot) {
  alert("This feed's title is: " + myResultsFeedRoot.feed.getTitle().getText());
  insertIntoMyFeed(myResultsFeedRoot);
}

新しい関数では、まず CalendarEventEntry コンストラクタを使用して新しいエントリを作成します。そのエントリを挿入し、挿入が完了したときにサービスが呼び出すコールバックを提供します。

function insertIntoMyFeed(feedRoot) {
  var newEntry = new google.gdata.calendar.CalendarEventEntry({
      authors: [{
        name: "Elizabeth Bennet",
        email: "liz@gmail.com"
      }],
      title: {
        type: 'text', 
        text: 'Tennis with Darcy'
      },
      content: {
        type: 'text', 
        text: 'Meet for a quick lesson'
      },
      locations: [{
        rel: "g.event",
        label: "Event location",
        valueString: "Netherfield Park tennis court"
      }],
      times: [{
        startTime: google.gdata.DateTime.fromIso8601("2007-09-23T18:00:00.000Z"),
        endTime: google.gdata.DateTime.fromIso8601("2007-09-23T19:00:00.000Z")
      }]
  });
  feedRoot.feed.insertEntry(newEntry, handleMyInsertedEntry, handleError);
}

コンストラクタで使用される各オブジェクト プロパティの名前は、そのプロパティに使用されるセッター メソッドの名前と一致していることに注意してください。(たとえば、対応する JSON フィールド名と照合するのは不可能)。

また、startTimeendTime に ISO 8601 の日時文字列を指定することはできないため、最初に fromIso8601() メソッドでこの文字列を実行する必要があります。

このサービスは挿入されたエントリのコピーを entryRoot オブジェクトとして返し、そのオブジェクトをコールバックに渡します。

function handleMyInsertedEntry(insertedEntryRoot) {
  alert("Entry inserted. The title is: " + insertedEntryRoot.entry.getTitle().getText());
  alert("The timestamp is: " + insertedEntryRoot.entry.getTimes()[0].startTime);
}

特定のエントリのリクエスト

特定のエントリをリクエストするには、まず handleMyInsertedEntry() 関数を変更して新しいエントリ リクエスト関数を呼び出します。

function handleMyInsertedEntry(insertedEntryRoot) {
  alert("Entry inserted. The title is: " + insertedEntryRoot.entry.getTitle().getText());
  alert("The timestamp is: " + insertedEntryRoot.entry.getTimes()[0].startTime);
  requestMySpecificEntry(insertedEntryRoot.entry.getSelfLink().getHref());
}

次のコードでは、前の例で挿入した特定のエントリをリクエストできます。

この一連の例では、挿入されたエントリをカレンダーがすでに返すため、そのエントリを取得する必要はありませんが、エントリの URI がわかっていれば同じ手法を適用できます。

function requestMySpecificEntry(entryURI) {
  myService.getEventsEntry(entryURI, handleMySpecificEntry, handleError);
}

function handleMySpecificEntry(retrievedEntryRoot) {
  myEntryRoot = retrievedEntryRoot; // Global variable for later use
  alert("This entry's title is: " + retrievedEntryRoot.entry.getTitle().getText());
}

この例と基本的に getEventsFeed() の例と同じですが、特定のエントリを取得するためにサービスの getEventEntry() メソッドを呼び出す点が異なります。また、URI は若干異なり、「デフォルト」を使用して認証済みユーザーのメイン カレンダーを参照し、末尾にエントリ ID があります

また、取得したエントリを後で使用できるように、グローバル変数にコピーします。

エントリの検索

全文検索を行うには、まず handleMySpecificEntry() 関数を変更して新しい検索関数を呼び出します。

function handleMySpecificEntry(retrievedEntryRoot) {
  myEntryRoot = retrievedEntryRoot; // Global variable for later use
  alert("This entry's title is: " + retrievedEntryRoot.entry.getTitle().getText());
  searchMyFeed();
}

次のコードを使用して、検索から最初の一致を取得します。

function searchMyFeed() {
  var myQuery = new google.gdata.calendar.CalendarEventQuery(feedUrl);
  myQuery.setFullTextQuery("Tennis");
  myQuery.setMaxResults(10);
  myService.getEventsFeed(myQuery, handleMyQueryResults, handleError);
}

function handleMyQueryResults(myResultsFeedRoot) {
  if (myResultsFeedRoot.feed.getEntries()[0]) {
    alert("The first search-match entry's title is: " + myResultsFeedRoot.feed.getEntries()[0].getTitle().getText());
  }
  else {
    alert("There are no entries that match the search query.");
  }
}

アイテムを更新する

既存のアイテムを更新するには、まず handleMyQueryResults() の末尾に行を追加して、新しい更新関数を呼び出します。

  updateMyEntry();

次に、以下のコードを使用します。この例では、以前取得したエントリ(前述の例ではグローバル オブジェクトに含まれていました)のタイトルを、「Tennis with Darcy」という古いテキストから「重要な会議」に変更します。myEntryRoot

function updateMyEntry() {
  myEntryRoot.entry.getTitle().setText("Important meeting");
  myEntryRoot.entry.updateEntry(handleMyUpdatedEntry, handleError);
}

function handleMyUpdatedEntry(updatedEntryRoot) {
  alert("Entry updated. The new title is: " + updatedEntryRoot.entry.getTitle().getText());
}

すべてのカレンダー メソッドと同様に、updateEntry() メソッドは、エントリの更新に使用する正しい編集 URI を自動的に決定するため、その URI を明示的に指定する必要はありません。

アイテムを削除する

更新されたエントリを削除するには、最初に handleMyUpdatedEntry() に次の行を追加します。

 deleteMyEntry(updatedEntryRoot);

次のコードを使用します。

function deleteMyEntry(updatedEntryRoot) {
  updatedEntryRoot.entry.deleteEntry(handleMyDeletedEntry, handleError);
}

function handleMyDeletedEntry() {
  alert("Entry deleted");
}

ここでも、deleteEntry() メソッドは、エントリの削除に使用する正しい編集 URI を自動的に決定します。

エントリは返されません。コールバックが呼び出されると、削除が成功したことを確認できます。削除が失敗した場合は、handleMyDeletedEntry() の代わりに handleError() を呼び出します。

ETag の使用

: ETag は Google Data Protocol v2.0 を実行しているサービスでのみ使用できます。

はじめに

Google Data JavaScript クライアント バージョン 2 では、ETag のサポートが導入されました。ETag は、特定のエントリの特定のバージョンを指定する識別子です。これは次の 2 つの場合に重要です。

  • 「条件付き取得」を行い、クライアントがエントリをリクエストし、クライアントがエントリを最後にリクエストした後にエントリが変更された場合にのみ、サーバーがエントリを送信する。
  • 複数のクライアントによって、変更内容が意図せず上書きされないようにするため。Data API は、クライアントでエントリに古い ETag が指定されている場合、更新と削除を行えば、この処理を行います。

ETag には弱と強の 2 種類があります。弱い ETag は常に W/ で始まります(例: W/"D08FQn8-eil7ImA9WxZbFEw")。弱い ETag はエントリが変更されたときに変更される保証がないため、HTTP では条件付き取得にのみ使用できます。強力な ETag は、特定のエントリの特定のバージョンを識別するもので、他のクライアントの変更を上書きしないように、条件付きの取得と更新または削除の両方に使用できます。この区別のため、クライアント ライブラリでは更新や削除のリクエストに対して脆弱な ETag を送信することはできません。

ETag は、サーバー応答の 2 つの場所にあります。

  • ETag HTTP ヘッダー内。
  • フィードまたはエントリで、gd:etag 属性として指定します。

サービスがバージョン 2 をサポートしている場合、各フィードとエントリ オブジェクトには、ETag の値を取得する getEtag() メソッドがあります。

JavaScript クライアントは、リクエストに ETag を含めるメソッドを 2 つサポートしています。1 つ目は新しい opt_params オブジェクトです。クライアント ライブラリのバージョン 2 の get/update/insert 機能はすべて、新しい opt_params パラメータを使用しています。このオブジェクトは、リクエストの作成時にオプションのパラメータを指定するために使用されます。現時点では、サポートされている唯一のパラメータは 'etag' です(ただし、他のパラメータも今後導入される可能性があります)。たとえば、次のように GET リクエストに ETag を追加できます。

var opt_params = {};
opt_params['etag'] = 'ETAG GOES HERE';
service.getFeed(uri, successHandler, errorHandler, opt_params);

フィードまたはエントリの setEtag() メソッドを呼び出して、ETag をフィードまたはエントリ オブジェクトに直接追加することもできます。

ETag について詳しくは、GData プロトコルのリファレンスをご覧ください。

ETag を使用してデータを取得する

ETag を使用すると、データを取得する際の帯域幅と実行時間を短縮できます。ETag は、If-None-Match header: を指定して GET リクエストに含めます。

If-None-Match: ETAG GOES HERE

ETag が現在のバージョンのフィードまたはエントリと一致する場合、サーバーは 304 NOT MODIFIED レスポンスと空の本文を返します。それ以外の場合、サーバーは 200 OK レスポンスとフィードデータまたはエントリデータを返します。

JavaScript クライアントで ETag を使用するには、リクエスト時に 'etag' パラメータを含めます。

var etag = feed.getEtag(); // Feed loaded from a previous request
var opt_params = {};
opt_params['etag'] = etag;
service.getFeed(feedUrl, successHandler, errorHandler, opt_params);

条件付き取得は、強力な ETag と弱い ETag の両方に対応しています。ETag が一致した場合、エラーハンドラは 304 レスポンスで呼び出されます。

function successHandler(feedRoot) {
  // 200 response
  // Update UI to display updates
}

function errorHandler(errorObj) {
  if (errorObj.cause.getStatus() == 304) {
    // 304 response, do nothing
  }
  // otherwise the response is some other error
}

JavaScript クライアントで ETag を使用する実用的な例については、Blogger を使用した条件付き取得のサンプルをご覧ください。このサンプルでは、Blogger を 5 秒間隔でポーリングしてブログの最新情報を確認します。変更があった場合、サンプルは投稿のリストを更新します。

ETag を使用してデータを更新、削除する

更新/削除リクエストで ETag を使用することで、複数のクライアントが意図せず変更を上書きすることを防ぐことができます。この場合、ETag は If-Match ヘッダーに含まれます。

If-Match: ETAG GOES HERE

リクエスト内の ETag がサーバー上の ETag と一致する場合、更新と削除は成功します。ただし、ETag の不一致はエントリが変更され、更新や削除が失敗することを示します。この場合、アプリケーションはデータの新しいインスタンスをリクエストしてから、更新/削除を再試行する必要があります。

場合によっては、エントリへの他の変更にかかわらず、強制的に変更を実行する必要があります。これを行うには、*If-Match ヘッダーに渡します。

If-Match: *

これは他のクライアントによる変更よりも優先されますので、ご注意ください。

ETag が強力なエントリのみ更新/削除できます。弱い ETag を指定すると、エラーが発生します。この状況を回避するため、JavaScript クライアントは更新および削除リクエストに脆弱な ETag を設定しません。

ETag の使用方法は条件付き取得の場合と同じです。

function updateData(entry, service) {
  var etag = entry.getEtag();
  var opt_params = {};
  opt_params['etag'] = etag; // Or use '*' to force an update.
  service.updateEntry(successHandler, errorHandler, opt_params);
}

function successHandler(response) {
  // Successful update
}

function errorHandler(errorObj) {
  // ERROR - Update failed. Could be due to an ETag mismatch, but check the
  // error message to make sure. An ETag error will be in the format:
  // Mismatch: etags = ["Qnc-fTVSLyp7ImA9WxJbFEsDRAw."], version = [1249675665358000]
}

更新を行う場合、ETag を 2 つの場所で指定できます。

  1. エントリ自体で、getEtag() メソッドと setEtag() メソッドを使用します。
  2. ヘッダー内で、(上記の)opt_params オブジェクトを使用します。

以前の GET リクエストで読み込んだエントリには、すでに ETag フィールドが設定されています。ただし、opt_params オブジェクトに同じ ETag を指定することは冗長です。エントリの本文と opt_params の両方で ETag が指定されている場合は、opt_params の ETag が優先されます。この処理はわかりにくいため、条件付き更新で問題が発生した場合は、エントリと opt_params オブジェクトの両方で ETag を確認してください。

google.gdata.Entry クラスには、独自の updateEntry() メソッドと deleteEntry() メソッドもあります。すでに ETag があるエントリクラスをリクエストに追加する必要はありません。クライアント ライブラリが自動的に追加します。例:

// entry was loaded from a previous request.  No need to specify
// an ETag in opt_params here, it is added automatically.
entry.deleteEntry(successHandler, errorHandler);

正しいタグを設定しなくても、ETag の利点を活かすことができます。ただし、'*' を使用して強制的に更新する場合は、必ず 'etag' = '*' を指定して opt_params オブジェクトを含める必要があります。

条件付き更新の動作は、連絡先の条件付き更新で確認できます。このサンプルでは、テスト用の連絡先グループを作成して、このサンプルで使用するデータをすべて作成します。サンプルの使用が終了したら、この連絡先グループを削除してください。このサンプルでは、連絡先グループのコンテンツを使用して 2 つの iframe を読み込みます。一方の iframe で更新を行って、もう一方の iframe での更新にどのように影響するかを確認できます。使用方法について詳しくは、サンプルをご覧ください。

サンプル

  • Blogger での条件付き取得 - 5 秒ごとに Blogger をポーリングし、更新を確認します。
  • 連絡先の条件付き更新 - 連絡先データを含む 2 つの iframe を表示します。連絡先の作成、更新、削除を行う際に、2 つのクライアントがどのようにやり取りするかを再現できます。

Reference

クライアント ライブラリで提供されるクラスとメソッドのリファレンス情報については、JavaScript クライアント ライブラリの API リファレンス(JSdoc 形式)をご覧ください。

トップへ戻る