Como usar a biblioteca de cliente JavaScript (v2.0)

Aviso: esta página é sobre as APIs mais antigas do Google, as APIs de dados do Google. Relevante apenas para as APIs listadas no diretório das APIs de dados do Google, muitas delas foram substituídas por APIs mais recentes. Para mais informações sobre uma nova API específica, consulte a documentação da nova API. Para informações sobre autorização de solicitações com uma API mais recente, consulte Autenticação e autorização de Contas do Google.

Este documento descreve como usar a biblioteca cliente JavaScript para enviar consultas da API de dados do Google e interpretar respostas retornadas.

O Google oferece um conjunto de bibliotecas de cliente em várias linguagens de programação para interagir com serviços que têm APIs de dados. Com essas bibliotecas, é possível criar solicitações de API, enviá-las para um serviço e receber respostas.

Este documento contém algumas informações gerais sobre o uso da biblioteca de cliente JavaScript, além de um conjunto de exemplos de usos comuns.

Público-alvo

Este documento é destinado a programadores de JavaScript que desejam criar aplicativos cliente que possam interagir com serviços de dados do Google.

Neste documento, presumimos que você entenda as ideias gerais por trás do protocolo das APIs de dados do Google. Você também precisa saber como programar em JavaScript.

Para informações sobre referências sobre as classes e os métodos fornecidos pela biblioteca de cliente, consulte a referência da API da biblioteca de cliente JavaScript (no formato JSdoc).

Este documento foi criado para ser lido em ordem. Cada exemplo usa exemplos anteriores.

Termos de Uso

Você concorda em obedecer aos Termos de Uso da biblioteca de cliente JavaScript do Google ao usar essa biblioteca.

Visão geral do modelo de dados e do fluxo de controle

A biblioteca cliente JavaScript usa um conjunto de classes para representar os elementos usados pelas APIs de dados do Google.

Observação: a representação dos dados é JSON, mas a biblioteca de cliente oferece uma camada de abstração para que você não precise trabalhar diretamente com dados JSON. Se você quiser trabalhar diretamente com JSON, sem a biblioteca de cliente, consulte Como usar JSON com APIs de dados do Google.

A biblioteca oferece métodos que permitem o envio assíncrono e o recebimento de dados de um serviço que tenha uma API de dados. Por exemplo, o método google.gdata.calendar.CalendarService.getEventsFeed() envia uma solicitação de feed ao Google Agenda. Um dos parâmetros transmitidos é uma função de continuação, também conhecida como callback. O serviço retorna o feed no formato JSON chamando a função de continuação. O cliente pode chamar vários métodos get para usar os dados na forma de objetos JavaScript.

Para adicionar uma nova entrada, crie a entrada usando as classes e os métodos da biblioteca de cliente e chame o método feed.insertEntry() para enviar a nova entrada ao serviço. Novamente, você fornece uma função de continuação, que o serviço chama quando a entrada é adicionada.

Se você não tem experiência com JavaScript, o fluxo de controle pode ser um pouco confuso. Depois de chamar um método como getEventsFeed() ou insertEntry(), na maioria dos casos, seu script termina. A execução é retomada na função de continuação quando o serviço retorna os dados solicitados. Portanto, tudo o que o cliente fizer com os dados retornados deverá ser feito na função de continuação ou chamado a partir dessa função. Talvez você precise criar algumas variáveis globais para usá-las em várias funções.

Para mais informações sobre esse estilo de programação, consulte "Estilo de programação contínua" na Wikipédia.

Sobre os ambientes compatíveis

No momento, só há suporte para aplicativos cliente JavaScript que são executados em uma página da Web em um navegador. Estes são os navegadores compatíveis:

  • Firefox 2.x e 3.x
  • Internet Explorer 6, 7 e 8
  • Safari 3.x e 4.x
  • Google Chrome (todas as versões)

A biblioteca de cliente JavaScript processa toda a comunicação com o servidor do serviço. Se você é um desenvolvedor JS experiente, pode estar pensando: "E se a mesma política de origem?" A biblioteca de cliente JavaScript permite que seu cliente envie solicitações de dados do Google de qualquer domínio, mantendo a conformidade com o modelo de segurança do navegador.

Para ter uma visão geral da autenticação com as APIs de dados do Google, consulte Visão geral da autenticação das APIs de dados do Google. O restante deste documento pressupõe que você conhece os conceitos básicos de funcionamento desse sistema.

Aplicativos de exemplo de cliente

Para ver a biblioteca de cliente JavaScript em ação, acesse nossa página de amostras.

Tutorial e exemplos

Os exemplos a seguir mostram como enviar várias solicitações de API de dados usando a biblioteca de cliente JavaScript.

Para explicar melhor, estes exemplos mostram como interagir com um serviço específico: o Google Agenda. Vamos indicar locais em que o Google Agenda é diferente de outros Serviços do Google, para ajudar você a adaptar esses exemplos para uso com outros serviços. Para mais informações sobre o Agenda, consulte o documento API Google Calendar Data.

Carregar a biblioteca

Para o seu cliente poder usar a biblioteca-cliente, ele deve solicitar o código da biblioteca-cliente a partir do servidor.

Comece usando uma tag <script> na seção <head> do documento HTML para buscar o carregador da API AJAX do Google:

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

É possível minimizar as idas e voltas aos servidores do Google e diminuir a latência pré-carregando a biblioteca. Para pré-carregar determinados pacotes diretamente do carregador da API AJAX do Google (sem usar google.load(), consulte abaixo), use o seguinte:

<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>

Observação: o URL do src do script precisa ser totalmente codificado. Por exemplo, o exemplo anterior é
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={modules:[{name:gdata,version:2.x,packages:[blogger,contacts]}]}"></script>.

Se você não estiver carregando módulos automaticamente, será possível carregar a biblioteca de cliente do Google Data usando o próximo exemplo no código de configuração JavaScript, depois de buscar o carregador comum. Essa chamada precisa ser feita na seção <head> do documento HTML (ou em um arquivo JavaScript incluído com uma tag <script> na seção <head> do documento HTML):

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

Como alternativa, é possível solicitar serviços específicos em vez de toda a biblioteca. Este exemplo faz o download apenas dos pacotes do Blogger e do Contatos:

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

O segundo parâmetro para google.load() é o número da versão solicitada da biblioteca cliente JavaScript.Nosso esquema de numeração de versões é modelado conforme o esquema usado pela API do Google Maps. Veja os possíveis números de versão e o que eles significam:

"1"
A penúltima revisão da versão principal 1.
"1.x"
A revisão mais recente da versão principal 1.
"1.s"
A revisão estável mais recente da versão principal 1. Às vezes, declaramos que uma determinada versão da biblioteca de cliente é "estável" com base nos feedbacks que recebemos de desenvolvedores. No entanto, é possível que essa versão não tenha os recursos mais recentes.
"1.0", "1.1" etc.
Uma versão específica da biblioteca, com um número de revisão principal e secundária especificado.

Depois de chamar google.load(), você precisará instruir o carregador a esperar até que a página termine de ser carregada e chamar o código:

google.setOnLoadCallback(getMyFeed);

Em que getMyFeed() é uma função definida na próxima seção deste documento. Use essa abordagem em vez de ter um gerenciador onload anexado ao elemento <body>.

Como solicitar um feed não autenticado

Para solicitar um feed não autenticado, adicione o seguinte código ao seu arquivo JavaScript ou a uma tag <script> no seu arquivo HTML.

No código a seguir, getMyFeed() é chamado primeiro (pelo carregador da API AJAX, conforme descrito na seção anterior).

Ele chama setupMyService() para criar uma conexão (representada por um objeto CalendarService) com o Google Agenda. O código de criação de serviço foi colocado em uma função separada para modularidade. Mais tarde, vamos modificar a função setupMyService(), dependendo das suas opções de autenticação.

Depois de configurar o serviço, o getMyFeed() chama o método getEventsFeed() da biblioteca de cliente para solicitar o feed.

Estamos especificando o URL do feed em uma variável global para que ele possa ser usado em funções posteriores. Neste exemplo, estamos usando o URL do feed público (não autenticado) de um usuário chamado liz@gmail.com. Você também pode usar default no lugar do endereço de e-mail do usuário para representar o usuário autenticado.

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);
}

Tornaremos myService uma variável global para facilitar o uso em funções futuras.

Para que o código acima funcione no seu próprio cliente, você precisa usar o endereço de e-mail de um usuário real em uma conta do Google Agenda com uma agenda compartilhada publicamente.

Observação: quando você cria um novo objeto CalendarService, a biblioteca de cliente chama um método chamado google.gdata.client.init(), que verifica se o navegador do cliente está sendo executado. Se ocorrer um erro, a biblioteca de cliente exibirá uma mensagem de erro para o usuário. Se você quiser processar esse tipo de erro, chame google.gdata.client.init(handleInitError) antes de criar o serviço, em que handleInitError() é a função. Se ocorrer um erro de inicialização, a função receberá um objeto de erro padrão. Você poderá fazer o que quiser com esse objeto.

Na chamada para getEventsFeed(), o segundo argumento é handleMyFeed, que é uma função de callback. Veja abaixo. O Google Agenda processará a solicitação e, se ela for bem-sucedida, passará um objeto "raiz do feed" com o feed solicitado para o callback. Uma raiz do feed é um objeto contêiner que contém um feed.

O terceiro argumento para getEventsFeed() é uma função opcional de tratamento de erros. Se a biblioteca de cliente encontrar um erro, ele vai chamar o gerenciador de erros especificado em vez da função de callback bem-sucedida. O objeto que a biblioteca de cliente transmite como o argumento para o gerenciador de erros é uma instância do objeto Error do JavaScript, com uma propriedade adicional de cause.

Veja as versões simples da função de callback e do gerenciador de erros:

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);
}

Tratamos os erros simplesmente exibindo-os ao usuário. O gerenciador de erros do seu cliente provavelmente é mais sofisticado. Em alguns contextos, não há nenhuma causa especificada. Nesses casos, o gerenciador de erros de exemplo volta a exibir a propriedade message padrão.

Como esse código não faz autenticação, você pode usá-lo apenas para receber um feed público.

Autenticando

A biblioteca de cliente JavaScript pode ser usada de dois modos. Se você estiver criando um gadget, ele usa um recurso chamado proxy OAuth para autenticação. Se estiver sendo acessado de um aplicativo JavaScript independente, ele usa o sistema de autenticação tmp. Para informações sobre autenticação, consulte o documento Visão geral da autenticação das APIs de dados do Google. O restante desta seção pressupõe que você conhece os conceitos básicos de funcionamento desse sistema.

Antes de usar a autenticação com o exemplo de código fornecido neste documento, altere o URL do feed de público para privado:

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

Como autenticar em um cliente da Web com tmp

O sistema de autorização "XPN para JavaScript" do Google não está mais disponível.

Em vez disso, recomendamos o uso do OAuth 2.0 para aplicativos do lado do cliente.

Como fazer autenticação para um gadget com o proxy OAuth

Confira uma breve visão geral do que acontece durante o processo de autenticação de um gadget:

  1. Seu gadget é carregado pela primeira vez e tenta acessar os dados do usuário usando uma das APIs de dados do Google.
  2. A solicitação falha porque o usuário ainda não concedeu acesso aos dados. O objeto de resposta contém um URL (em response.oauthApprovalUrl) para a página de aprovação do OAuth. Seu gadget deve fornecer um método para iniciar uma nova janela com esse URL.
  3. Na página de aprovação, o usuário decide conceder/negar acesso ao seu gadget. Se for bem-sucedido, o usuário será direcionado para a página oauth_callback especificada. Use o http://oauth.gmodules.com/gadgets/oauthcallback para ter a melhor experiência do usuário.
  4. Em seguida, o usuário fecha a janela pop-up. Para ajudar a notificar seu gadget de que o usuário concedeu a aprovação, fornecemos um gerenciador de pop-ups que pode ser usado para detectar o fechamento da janela de aprovação. Como alternativa, o widget pode mostrar um link (por exemplo, "Aprovei o acesso") para o usuário clicar manualmente após o fechamento dessa janela.
  5. Seu gadget tentará acessar a API de dados do Google novamente solicitando novamente os dados do usuário. Esta tentativa foi bem-sucedida.
  6. Seu gadget está autenticado e pode começar a funcionar normalmente.

No seu gadget, adicione um elemento <OAuth> na seção <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>

Nesta seção, altere os seguintes parâmetros de consulta:

  • scope

    Um parâmetro obrigatório no URL da solicitação. Seu gadget só poderá acessar os dados do(s) scope(s) usado(s) neste parâmetro. Neste exemplo, o gadget acessará os seus dados do Blogger e do Google Agenda. Um gadget pode solicitar dados de um ou de vários escopos, como neste exemplo.

  • oauth_callback

    Um parâmetro opcional no URL de autorização. A página de aprovação do OAuth vai redirecionar você para esse URL depois que o usuário aprovar o acesso aos dados. É possível deixar esse parâmetro fora de você, defini-lo como sua própria "página aprovada" ou usar http://oauth.gmodules.com/gadgets/oauthcallback. A segunda oferece a melhor experiência do usuário quando ele instala o gadget pela primeira vez. Essa página fornece um snippet de JavaScript que fecha automaticamente a janela pop-up.

Em seguida, carregue a biblioteca de cliente JavaScript na seção <Content> do seu gadget. Modifique a função setupMyService() dos exemplos anteriores para chamar o método useOAuth() do objeto de serviço. Isso informa ao gadget para usar o proxy OAuth para autenticação em vez de tmp. Use este modelo abaixo para começar:

<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>

A chamada para google.accounts.user.login(scope) foi removida. O proxy processa a autenticação para você.

Para mais informações sobre como criar gadgets da API Google Data, incluindo detalhes sobre o que fetchData() precisa conter, consulte nosso artigo sobre Como criar um gadget de dados do Google ou confira a documentação completa sobre Como criar gadgets OAuth.

Inserir um novo item

Para criar um novo evento da agenda, continue a execução no exemplo anterior modificando o final da função handleMyFeed() para chamar uma nova função:

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

Na nova função, use o construtor CalendarEventEntry para criar a nova entrada. Em seguida, insira a entrada, fornecendo um callback para o serviço chamar quando a inserção for concluída.

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);
}

O nome de cada propriedade de objeto usada no construtor corresponde ao nome do método setter usado para essa propriedade. Em vez de, por exemplo, corresponder ao nome do campo JSON correspondente.

Observe que não é possível fornecer strings de data e hora ISO 8601 para startTime e endTime. Primeiro, é necessário executar essas strings pelo método fromIso8601().

O serviço retorna uma cópia da entrada inserida como um objeto entryRoot e transmite esse objeto para o callback:

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

Como solicitar uma entrada específica

Para solicitar uma entrada específica, primeiro modifique a função handleMyInsertedEntry() para chamar uma nova função de solicitação de entrada:

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());
}

O código a seguir permite solicitar a entrada específica que você inseriu no exemplo anterior.

No contexto desta série de exemplos, recuperar essa entrada não é necessário porque o Google Agenda já retornou a entrada inserida, mas a mesma técnica pode ser aplicada sempre que você souber o URI de uma entrada.

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());
}

Esse exemplo é basicamente o mesmo que o exemplo getEventsFeed(), exceto que estamos chamando o método getEventEntry() do serviço para receber uma entrada específica, e o URI é um pouco diferente. Ele usa "default" para se referir à agenda principal do usuário autenticado e tem um ID de entrada no final.

Além disso, precisamos poder usar a entrada recuperada mais tarde. Por isso, vamos copiá-la para uma variável global.

Como pesquisar entradas

Para realizar uma pesquisa de texto completo, primeiro modifique a função handleMySpecificEntry() para chamar uma nova função de pesquisa:

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

Em seguida, para recuperar a primeira correspondência da pesquisa, use o seguinte código:

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.");
  }
}

Como atualizar um item

Para atualizar um item existente, primeiro adicione uma linha ao fim de handleMyQueryResults() para chamar uma nova função de atualização:

  updateMyEntry();

Em seguida, use o código a seguir. Neste exemplo, estamos mudando o título da entrada recuperada anteriormente (que estava no objeto global chamado myEntryRoot em um exemplo anterior) de "Tennis with Darcy" para "Reunião importante".

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());
}

Como acontece com todos os métodos do Agenda, o updateEntry() determina automaticamente o URI de edição correto a ser usado na atualização da entrada. Dessa forma, você não precisa informar esse URI explicitamente.

Excluir um item

Para excluir a entrada atualizada, primeiro adicione uma linha a handleMyUpdatedEntry():

 deleteMyEntry(updatedEntryRoot);

Em seguida, use o seguinte código:

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

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

Novamente, o método deleteEntry() determina automaticamente o URI de edição correto a ser usado na exclusão da entrada.

Observe que nenhuma entrada é retornada. Se o callback for chamado, saberemos que a exclusão foi bem-sucedida. Se a exclusão falhar, deleteEntry() chamará handleError() em vez de handleMyDeletedEntry().

Como usar ETags

Observação: as ETags só podem ser usadas com serviços que executam o Protocolo de dados v2.0 do Google.

Introdução

A versão 2 do cliente JavaScript de dados do Google introduz o suporte a ETags. As ETags são identificadores que especificam uma versão específica de uma entrada. Isso é importante em dois casos:

  • Fazer uma "recuperação condicional", em que um cliente solicita uma entrada, e o servidor envia a entrada somente se ela tiver mudado desde a última vez que o cliente a solicitou.
  • Garantir que vários clientes não substituam acidentalmente as alterações uns dos outros. As APIs de dados fazem isso com atualizações e exclusões se o cliente especificar uma ETag antiga para a entrada.

Há dois tipos de ETags: fraca e forte. Uma ETag fraca sempre começa com W/, por exemplo: W/"D08FQn8-eil7ImA9WxZbFEw". Não há garantia de que as ETags fracas mudarão quando a entrada mudar, então o HTTP permite que elas sejam usadas somente para recuperação condicional. As ETags fortes identificam uma versão específica de uma entrada específica e podem ser usadas para recuperação condicional e durante atualizações ou exclusões para evitar substituir mudanças de outros clientes. Devido a essa distinção, a biblioteca de cliente não permitirá que você envie ETags fracas com uma solicitação de atualização ou exclusão.

As ETags podem ser encontradas em dois locais na resposta do servidor:

  • No cabeçalho HTTP ETag.
  • No feed/entrada, como o atributo gd:etag.

Se um serviço for compatível com a versão 2, cada feed e objeto de entrada vai ter um método getEtag() para recuperar o valor da ETag.

O cliente JavaScript é compatível com dois métodos para incluir ETags com uma solicitação. O primeiro é o novo objeto opt_params. Todas as funções get/update/insert na versão 2 da biblioteca de cliente têm um novo parâmetro opt_params. Esse objeto é usado para especificar parâmetros opcionais ao fazer uma solicitação. Por enquanto, 'etag' é o único parâmetro opcional compatível, embora outros parâmetros possam ser introduzidos no futuro. Por exemplo, é possível adicionar uma ETag a uma solicitação GET desta forma:

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

Também é possível adicionar uma ETag diretamente a um feed ou objeto de entrada chamando o método setEtag() no feed/entrada.

Saiba mais sobre ETags na Referência do protocolo de dados do Google.

Como usar ETags para recuperar dados

As ETags ajudam a reduzir a largura de banda e o tempo de execução ao recuperar dados. Uma ETag pode ser incluída em uma solicitação GET com o If-None-Match header:

If-None-Match: ETAG GOES HERE

Se a ETag corresponder à versão atual do feed ou da entrada, o servidor responderá com uma resposta 304 NOT MODIFIED e um corpo vazio. Caso contrário, o servidor vai responder com uma resposta 200 OK e os dados do feed ou da entrada.

É possível usar ETags no cliente JavaScript incluindo um parâmetro 'etag' ao fazer a solicitação:

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

As recuperações condicionais funcionam com ETags fortes e fracas. Se a ETag corresponder, o gerenciador de erros será chamado com uma resposta 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
}

Confira o exemplo Recuperação condicional usando o Blogger para ver um exemplo mais prático de como usar ETags no cliente JavaScript. Esta amostra pesquisa o Blogger em intervalos de cinco segundos buscando atualizações do seu blog. Quando há alterações, o exemplo atualiza uma lista de postagens.

Como usar ETags para atualizar e excluir dados

O uso de ETags em solicitações de atualização/exclusão garante que vários clientes não substituam acidentalmente as alterações uns dos outros. Nesse caso, uma ETag está incluída no cabeçalho If-Match:

If-Match: ETAG GOES HERE

Se a ETag na solicitação corresponder à ETag no servidor, a atualização/exclusão será bem-sucedida. No entanto, uma incompatibilidade de ETag indica que a entrada mudou, e a atualização/exclusão falha. Nesse caso, o aplicativo precisa solicitar uma nova instância dos dados e tentar atualizar/excluir novamente.

Em determinados casos, é necessário forçar as alterações, independentemente de outras alterações na entrada. Para isso, transmita um * para o cabeçalho If-Match:

If-Match: *

Tenha em mente que isso substituirá as alterações feitas por outros clientes. Portanto, use-as com cuidado.

Só é possível atualizar/excluir uma entrada com uma ETag forte. Especificar uma ETag fraca resultará em erro. Para se proteger contra esse caso, o cliente JavaScript não vai definir ETags fracas em solicitações de atualização e exclusão.

As ETags são usadas da mesma forma que as recuperações condicionais:

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

Ao fazer atualizações, uma ETag pode ser especificada em dois lugares:

  1. Na própria entrada, usando os métodos getEtag() e setEtag().
  2. No cabeçalho, usando o objeto opt_params (como demonstrado acima).

Uma entrada carregada de uma solicitação GET anterior já terá um campo ETag definido. Portanto, especificar a mesma ETag no objeto opt_params é redundante. Caso uma ETag seja especificada no corpo da entrada e no opt_params, a ETag na opt_params terá precedência. Isso pode ser um pouco confuso, então se você tiver problemas com atualizações condicionais, verifique a ETag na entrada e no objeto opt_params.

Para facilitar, as classes google.gdata.Entry também têm os próprios métodos updateEntry() e deleteEntry(). Se a classe de entrada já tiver uma ETag, não será necessário adicioná-la à solicitação. A biblioteca de cliente fará isso automaticamente. Exemplo:

// 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);

Com isso, você tem a vantagem de usar ETags sem precisar defini-las corretamente. No entanto, se você quiser forçar a atualização usando '*', sempre inclua o objeto opt_params com 'etag' = '*'.

Você pode ver as atualizações condicionais em Atualizações condicionais em Contatos. O exemplo primeiro cria um grupo de contatos de teste em que todos os dados usados por ele serão criados. Você pode excluir esse grupo quando terminar de usar o exemplo. Em seguida, o exemplo carrega dois iframes com o conteúdo do grupo de contatos. É possível fazer atualizações em um iframe e ver como isso afeta as atualizações em outro iframe. Acesse a amostra para mais detalhes sobre como usá-la.

Exemplos

Referência

Para informações sobre referências sobre as classes e os métodos fornecidos pela biblioteca de cliente, consulte a referência da API da biblioteca de cliente JavaScript (no formato JSdoc).

Voltar ao início