Pedidos em lote

Como resultado da descontinuação dos pontos finais HTTP em lote globais, os pedidos HTTP em lote que têm como destino apenas as APIs BigQuery vão deixar de funcionar a 2 de junho de 2025. Se a sua aplicação estiver a enviar pedidos HTTP em lote, substitua os pedidos HTTP em lote por pedidos HTTP individuais antes de 2 de junho de 2025.

Para informações sobre a descontinuação, consulte a secção de Perguntas frequentes seguinte. Para ver documentação sobre como processar pedidos HTTP em lote, consulte o artigo Processamento em lote de pedidos.

Perguntas frequentes sobre a descontinuação da API HTTP em lote do BigQuery

Por que motivo os pedidos HTTP em lote do BigQuery foram descontinuados?

O suporte para pontos finais de lotes HTTP globais baseava-se numa arquitetura que usava um proxy partilhado único para receber pedidos para todas as APIs. À medida que a Google avançou para uma arquitetura de alto desempenho mais distribuída, em que os pedidos são enviados diretamente para o servidor da API adequado, deixámos de suportar estes pontos finais globais.

A descontinuação dos pedidos HTTP em lote do BigQuery é o passo seguinte. O serviço BigQuery também é distribuído. Os métodos de CPS elevado são processados por back-ends dedicados. Todas as regiões estão isoladas, mas os pedidos HTTP em lote podem causar a propagação de pedidos entre regiões. Isto torna o processamento em lote ineficiente e pode resultar numa latência de processamento mais elevada, o que é o oposto do objetivo original do suporte de pedidos HTTP em lote.

O que é especificamente descontinuado?

Os seguintes métodos de pedido em lote de interação com as APIs BigQuery deixarão de funcionar:

Como posso migrar?

A maioria dos utilizadores do BigQuery não usa pedidos HTTP em lote. Se ainda estiver a usar pedidos em lote, use os exemplos seguintes para substituir os pedidos HTTP em lote por pedidos HTTP individuais.

REST

Envie pedidos HTTP individuais, conforme documentado na secção de referência da API BigQuery. Não combine os seus pedidos em lotes através do caminho /batch/v2/bigquery.

JavaScript

Se estiver a usar JavaScript, começa com um bloco de código com o seguinte aspeto: this:

// Notice that the outer batch request contains inner API requests
// for two different APIs.

// Request to urlshortener API
request1 = gapi.client.urlshortener.url.get({"shortUrl":
"http://goo.gl/fbsS"});

// Request to zoo API
request2 = gapi.client.zoo.animals.list();

// Request to urlshortener API
request3 = gapi.client.urlshortener.url.get({"shortUrl":
"https://goo.gl/XYFuPH"});

// Request to zoo API
request4 = gapi.client.zoo.animal().get({"name": "giraffe"});

// Creating a batch request object
batchRequest = gapi.client.newBatch();
// adding the 4 batch requests
batchRequest.add(request1);
batchRequest.add(request2);
batchRequest.add(request3);
batchRequest.add(request4);
// print the batch request
batchRequest.then(x=>console.log(x))

Substitua o bloco de código anterior por um bloco de código com o seguinte aspeto:

// Request to urlshortener API
request1 = gapi.client.urlshortener.url.get({"shortUrl": "http://goo.gl/fbsS"});

// Request to zoo API
request2 = gapi.client.zoo.animals.list();

// Request to urlshortener API
request3 = gapi.client.urlshortener.url.get({"shortUrl": "http://goo.gl/fbsS"})

// Request to zoo API
request4 = gapi.client.zoo.animals.list();

// print the 4 individual requests
Promise.all([request1, request2, request3, request4])
    .then(x=>console.log(x));

Python

Se estiver a usar Python, começa com um bloco de código semelhante a este:

from apiclient.http import BatchHttpRequest

def insert_animal(request_id, response, exception):
  if exception is not None: # Do something with the exception
    pass
  else: # Do something with the response
    pass

service = build('farm', 'v2')
batch = service.new_batch_http_request(callback=insert_animal)
batch.add(service.animals().insert(name="sheep"))
batch.add(service.animals().insert(name="pig"))
batch.add(service.animals().insert(name="llama"))
batch.execute(http=http)

Substitua o bloco de código anterior por um bloco de código com o seguinte aspeto:

# import a new API to create a thread pool
from concurrent.futures import ThreadPoolExecutor as PoolExecutor

def run_it(request):
  print(request.execute())

service = build('farm', 'v2')
request1 = service.animals().insert(name="sheep")
request2 = service.animals().insert(name="pig")
request3 = service.animals().insert(name="llama")
with PoolExecutor(max_workers=4) as executor:
  for _ in executor.map(run_it,[request1, request2, request3]):
    pass

Outros idiomas

Semelhante aos exemplos anteriores, substitua as chamadas BatchRequest por pedidos individuais.

Receba apoio técnico para a migração

Para obter ajuda com a migração, pode fazer perguntas no Stack Overflow. Os engenheiros da Google monitorizam e respondem a perguntas com a etiqueta google-bigquery. Use esta etiqueta quando fizer perguntas. Tentamos responder a todas as perguntas num período razoável.

Pedidos em lote

Este documento mostra como agrupar chamadas da API para reduzir o número de ligações HTTP que o cliente tem de fazer.

Este documento aborda especificamente a criação de um pedido em lote através do envio de um pedido HTTP. Se, em alternativa, estiver a usar uma biblioteca cliente da Google para fazer um pedido em lote, consulte a documentação da biblioteca cliente.

Vista geral

Cada ligação HTTP que o seu cliente faz resulta numa determinada quantidade de sobrecarga. A API BigQuery suporta o processamento em lote, para permitir que o seu cliente coloque várias chamadas API num único pedido HTTP.

Exemplos de situações em que pode querer usar o processamento em lote:

  • Acabou de começar a usar a API e tem muitos dados para carregar.
  • Um utilizador fez alterações aos dados enquanto a sua aplicação estava offline (sem ligação à Internet), pelo que a aplicação tem de sincronizar os respetivos dados locais com o servidor enviando muitas atualizações e eliminações.

Em cada caso, em vez de enviar cada chamada separadamente, pode agrupá-las numa única solicitação HTTP. Todos os pedidos internos têm de ser enviados para a mesma API Google.

Tem um limite de 1000 chamadas num único pedido em lote. Se tiver de fazer mais chamadas do que isso, use vários pedidos em lote.

Nota: o sistema de processamento em lote da API BigQuery usa a mesma sintaxe que o sistema de processamento em lote OData, mas a semântica é diferente.

Detalhes do lote

Um pedido em lote consiste em várias chamadas API combinadas num pedido HTTP, que pode ser enviado para o batchPath especificado no documento de descoberta da API. O caminho predefinido é /batch/api_name/api_version. Esta secção descreve a sintaxe de lotes em detalhe. Mais adiante, encontra um exemplo.

Nota: um conjunto de pedidos agrupados conta para o seu limite de utilização como n pedidos e não como um pedido.n O pedido em lote é separado num conjunto de pedidos antes do processamento.

Formato de um pedido em lote

Um pedido em lote é um único pedido HTTP padrão que contém várias chamadas da API BigQuery, usando o tipo de conteúdo multipart/mixed. Nesse pedido HTTP principal, cada uma das partes contém um pedido HTTP aninhado.

Cada parte começa com o seu próprio cabeçalho HTTP Content-Type: application/http. Também pode ter um cabeçalho Content-ID opcional. No entanto, os cabeçalhos das partes servem apenas para marcar o início da parte e estão separados do pedido aninhado. Depois de o servidor anular a união do pedido em lote em pedidos separados, os cabeçalhos das partes são ignorados.

O corpo de cada parte é um pedido HTTP completo, com o seu próprio verbo, URL, cabeçalhos e corpo. O pedido HTTP só pode conter a parte do caminho do URL. Não são permitidos URLs completos em pedidos em lote.

Os cabeçalhos HTTP do pedido em lote externo, exceto os cabeçalhos Content-, como Content-Type, aplicam-se a todos os pedidos no lote. Se especificar um determinado cabeçalho HTTP no pedido exterior e numa chamada individual, o valor do cabeçalho da chamada individual substitui o valor do cabeçalho do pedido em lote exterior. Os cabeçalhos de uma chamada individual aplicam-se apenas a essa chamada.

Por exemplo, se fornecer um cabeçalho de autorização para uma chamada específica, esse cabeçalho aplica-se apenas a essa chamada. Se fornecer um cabeçalho de autorização para o pedido externo, esse cabeçalho aplica-se a todas as chamadas individuais, a menos que o substituam pelos seus próprios cabeçalhos de autorização.

Quando o servidor recebe o pedido em lote, aplica os parâmetros de consulta e os cabeçalhos do pedido externo (conforme adequado) a cada parte e, em seguida, trata cada parte como se fosse um pedido HTTP separado.

Resposta a um pedido em lote

A resposta do servidor é uma única resposta HTTP padrão com um tipo de conteúdo multipart/mixed. Cada parte é a resposta a um dos pedidos no pedido em lote, na mesma ordem dos pedidos.

Tal como as partes no pedido, cada parte da resposta contém uma resposta HTTP completa, incluindo um código de estado, cabeçalhos e corpo. Tal como as partes no pedido, cada parte da resposta é precedida por um cabeçalho Content-Type que marca o início da parte.

Se uma determinada parte do pedido tiver um cabeçalho Content-ID, a parte correspondente da resposta tem um cabeçalho Content-ID correspondente, com o valor original precedido pela string response-, conforme mostrado no exemplo seguinte.

Nota: o servidor pode executar as suas chamadas por qualquer ordem. Não conte com a execução pela ordem em que as especificou. Se quiser garantir que duas chamadas ocorrem numa determinada ordem, não pode enviá-las num único pedido. Em alternativa, envie a primeira sozinha e, em seguida, aguarde a resposta à primeira antes de enviar a segunda.

Exemplo

O exemplo seguinte mostra a utilização do processamento em lote com uma API de demonstração genérica (fictícia) denominada API Farm. No entanto, os mesmos conceitos aplicam-se à API BigQuery.

Exemplo de pedido em lote

POST /batch/farm/v1 HTTP/1.1
Authorization: Bearer your_auth_token
Host: www.googleapis.com
Content-Type: multipart/mixed; boundary=batch_foobarbaz
Content-Length: total_content_length

--batch_foobarbaz
Content-Type: application/http
Content-ID: <item1:12930812@barnyard.example.com>

GET /farm/v1/animals/pony

--batch_foobarbaz
Content-Type: application/http
Content-ID: <item2:12930812@barnyard.example.com>

PUT /farm/v1/animals/sheep
Content-Type: application/json
Content-Length: part_content_length
If-Match: "etag/sheep"

{
  "animalName": "sheep",
  "animalAge": "5"
  "peltColor": "green",
}

--batch_foobarbaz
Content-Type: application/http
Content-ID: <item3:12930812@barnyard.example.com>

GET /farm/v1/animals
If-None-Match: "etag/animals"

--batch_foobarbaz--

Exemplo de resposta em lote

Esta é a resposta ao pedido de exemplo na secção anterior.

HTTP/1.1 200
Content-Length: response_total_content_length
Content-Type: multipart/mixed; boundary=batch_foobarbaz

--batch_foobarbaz
Content-Type: application/http
Content-ID: <response-item1:12930812@barnyard.example.com>

HTTP/1.1 200 OK
Content-Type application/json
Content-Length: response_part_1_content_length
ETag: "etag/pony"

{
  "kind": "farm#animal",
  "etag": "etag/pony",
  "selfLink": "/farm/v1/animals/pony",
  "animalName": "pony",
  "animalAge": 34,
  "peltColor": "white"
}

--batch_foobarbaz
Content-Type: application/http
Content-ID: <response-item2:12930812@barnyard.example.com>

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: response_part_2_content_length
ETag: "etag/sheep"

{
  "kind": "farm#animal",
  "etag": "etag/sheep",
  "selfLink": "/farm/v1/animals/sheep",
  "animalName": "sheep",
  "animalAge": 5,
  "peltColor": "green"
}

--batch_foobarbaz
Content-Type: application/http
Content-ID: <response-item3:12930812@barnyard.example.com>

HTTP/1.1 304 Not Modified
ETag: "etag/animals"

--batch_foobarbaz--