Uploads de API
Com o recurso de upload de mídia, a API BigQuery pode ser usada para armazenar dados na nuvem e disponibilizá-los para o servidor. É possível fazer upload de fotos, vídeos, arquivos PDF, arquivos zip e qualquer outro tipo de dado.
Opções de upload
Com a API BigQuery, é possível fazer upload de certos tipos de dados binários ou mídia. As características específicas dos dados passíveis de envio são especificadas na página de referência de qualquer método compatível com uploads de mídia:
- Tamanho máximo do arquivo de upload: a quantidade máxima de dados que é possível armazenar com este método.
- Tipos de mídia MIME aceitos: os tipos de dados binários que é possível armazenar usando este método.
É possível fazer solicitações de upload de uma das maneiras a seguir. Especifique o método que você está usando com o parâmetro de solicitação uploadType
.
- Upload de várias partes:
uploadType=multipart
. Para transferência rápida de arquivos e metadados menores. Transfere o arquivo junto com os metadados que o descrevem, tudo em uma solicitação. - Upload retomável:
uploadType=resumable
. Para transferência confiável, especialmente importante para arquivos maiores. Com esse método, você usa uma solicitação de inicialização de sessão, que opcionalmente pode incluir metadados. Essa é uma boa estratégia para usar na maioria dos aplicativos, já que também funciona para arquivos menores ao custo de uma solicitação HTTP extra por upload.
Ao fazer upload de mídias, use um URI especial. Na verdade, os métodos compatíveis com uploads de mídia têm dois endpoints de URI:
O URI /upload, para a mídia. O formato do endpoint de upload é o URI de recurso padrão com um prefixo "/upload". Use esse URI ao transferir os dados de mídia.
Exemplo:
POST /upload/bigquery/v2/projects/projectId/jobs
O URI de recurso padrão, para os metadados. Se o recurso contiver campos de dados, esses campos serão usados para armazenar metadados que descrevem o arquivo enviado. Use esse URI ao criar ou atualizar valores de metadados.
Exemplo:
POST /bigquery/v2/projects/projectId/jobs
Upload de várias partes
Se você tiver metadados que pretende enviar junto com os dados de upload, poderá fazer uma única solicitação multipart/related
. Essa é uma boa opção quando os dados que você está enviando são pequenos o bastante para serem enviados novamente por completo em caso de falha da conexão.
Para usar o upload de várias partes, faça uma solicitação POST
ao URI /upload do método e adicione o parâmetro de consulta uploadType=multipart
. Por exemplo:
POST https://www.googleapis.com/upload/bigquery/v2/projects/projectId/jobs?uploadType=multipart
Os cabeçalhos HTTP de nível superior a serem usados em uma solicitação de upload de várias partes incluem os abaixo:
Content-Type
. Defina como "multipart/related" e inclua a string de limite que você está usando para identificar as partes da solicitação.Content-Length
. Defina com o número total de bytes no corpo da solicitação. A parte de mídia da solicitação precisa ser menor que o tamanho máximo de arquivo especificado para este método.
O corpo da solicitação é formatado como um tipo de conteúdo multipart/related
[RFC2387] e contém exatamente duas partes. As partes são identificadas por uma string de limite, e a string de limite final é acompanhada por dois hifens.
Cada parte da solicitação de várias partes precisa de um cabeçalho Content-Type
extra:
- Parte de metadados: precisa vir em primeiro lugar, e
Content-Type
precisa corresponder a um dos formatos de metadados aceitos. - Parte de mídia: precisa vir depois, e
Content-Type
precisa corresponder a um dos tipos MIME de mídia aceitos pelo método.
Consulte a referência da API para uma lista com os tipos MIME de mídia aceitos por cada método e os limites de tamanho dos arquivos enviados.
Observação: para criar ou atualizar apenas a porção de metadados, sem fazer o upload de dados associados, basta enviar uma solicitação POST
ou PUT
para o endpoint de recurso padrão: https://www.googleapis.com/bigquery/v2/projects/projectId/jobs
Exemplo: upload de várias partes
O exemplo abaixo mostra uma solicitação de upload de várias partes para a API BigQuery.
POST /upload/bigquery/v2/projects/projectId/jobs?uploadType=multipart HTTP/1.1 Host: www.googleapis.com Authorization: Bearer your_auth_token Content-Type: multipart/related; boundary=foo_bar_baz Content-Length: number_of_bytes_in_entire_request_body --foo_bar_baz Content-Type: application/json; charset=UTF-8 { "configuration": { "load": { "sourceFormat": "NEWLINE_DELIMITED_JSON", "schema": { "fields": [ {"name": "f1", "type": "STRING"}, {"name": "f2", "type": "INTEGER"} ] }, "destinationTable": { "projectId": "projectId", "datasetId": "datasetId", "tableId": "tableId" } } } } --foo_bar_baz Content-Type: */* CSV, JSON, AVRO, PARQUET, or ORC data --foo_bar_baz--
Se a solicitação for bem-sucedida, o servidor retornará o código de status HTTP 200 OK
juntamente com todos os metadados:
HTTP/1.1 200 Content-Type: application/json { "configuration": { "load": { "sourceFormat": "NEWLINE_DELIMITED_JSON", "schema": { "fields": [ {"name": "f1", "type": "STRING"}, {"name": "f2", "type": "INTEGER"} ] }, "destinationTable": { "projectId": "projectId", "datasetId": "datasetId", "tableId": "tableId" } } } }
Upload retomável
Para fazer upload de arquivos de dados de maneira mais confiável, é possível usar o protocolo de upload retomável. Esse protocolo permite retomar uma operação de upload após uma falha de comunicação ter interrompido o fluxo de dados. Especialmente útil na transferência arquivos grandes e na probabilidade de uma interrupção de rede ou outra falha de transmissão ser alta, por exemplo, ao fazer upload de um aplicativo cliente para dispositivos móveis. Também é possível reduzir o uso da largura de banda em caso de falhas de rede, e não é necessário reiniciar os uploads de arquivos grandes desde o começo.
Estas são as etapas para usar o upload retomável:
- Inicie uma sessão retomável. Faça uma solicitação inicial para o URI de upload que inclui os metadados, se houver.
- Salve o URI da sessão retomável. Salve o URI da sessão retornado na resposta da solicitação inicial. Use-o nas solicitações restantes dessa sessão.
- Faça upload do arquivo. Envie o arquivo de mídia para o URI da sessão retomável.
Além disso, os aplicativos que usam o upload retomável precisam ter código para retomar um upload interrompido. Se um upload for interrompido, descubra quantos dados foram recebidos com êxito e retome o upload a partir desse ponto.
Observação: um URI de upload expira após uma semana.
Etapa 1: iniciar uma sessão retomável
Para iniciar um upload retomável, faça uma solicitação POST
ao URI /upload do método e adicione o parâmetro de consulta uploadType=resumable
. Por exemplo:
POST https://www.googleapis.com/upload/bigquery/v2/projects/projectId/jobs?uploadType=resumable
Para essa solicitação inicial, o corpo está vazio ou contém apenas os metadados. Você transferirá o conteúdo real do arquivo a ser enviado em solicitações subsequentes.
Use os cabeçalhos HTTP a seguir com a solicitação inicial:X-Upload-Content-Type
. Defina com o tipo MIME de mídia dos dados de upload a serem transferidos em solicitações subsequentes.X-Upload-Content-Length
. Defina com o número de bytes de dados de upload a serem transferidos em solicitações subsequentes. Se o tamanho for desconhecido no momento da solicitação, omita esse cabeçalho.- Se estiver fornecendo metadados:
Content-Type
. Defina de acordo com o tipo de dados dos metadados. Content-Length
. Defina como o número de bytes fornecidos no corpo dessa solicitação inicial. Isso não é obrigatório se você estiver usando a codificação de transferência em partes.
Consulte a referência da API para uma lista com os tipos MIME de mídia aceitos por cada método e os limites de tamanho dos arquivos enviados.
Exemplo: solicitação de início de sessão retomável
O exemplo a seguir mostra como iniciar uma sessão retomável para a API BigQuery.
POST /upload/bigquery/v2/projects/projectId/jobs?uploadType=resumable HTTP/1.1 Host: www.googleapis.com Authorization: Bearer your_auth_token Content-Length: 38 Content-Type: application/json; charset=UTF-8 X-Upload-Content-Type: */* X-Upload-Content-Length: 2000000 { "configuration": { "load": { "sourceFormat": "NEWLINE_DELIMITED_JSON", "schema": { "fields": [ {"name": "f1", "type": "STRING"}, {"name": "f2", "type": "INTEGER"} ] }, "destinationTable": { "projectId": "projectId", "datasetId": "datasetId", "tableId": "tableId" } } } }
Observação: para uma solicitação de atualização retomável inicial sem metadados, deixe o corpo da solicitação vazio e defina o cabeçalho Content-Length
como 0
.
A seção a seguir descreve como lidar com a resposta.
Etapa 2: salvar o URI da sessão retomável
Se a solicitação de início da sessão for bem-sucedida, o servidor da API responderá com um código de status HTTP 200 OK
. Além disso, ele fornece um cabeçalho Location
que especifica o URI da sessão retomável. O cabeçalho Location
, mostrado no exemplo abaixo, inclui uma parte do parâmetro de consulta upload_id
que fornece o código de upload exclusivo a ser usado para essa sessão.
Exemplo: resposta de iniciação da sessão retomável
Esta é a resposta à solicitação na etapa 1:
HTTP/1.1 200 OK Location: https://www.googleapis.com/upload/bigquery/v2/projects/projectId/jobs?uploadType=resumable&upload_id=xa298sd_sdlkj2 Content-Length: 0
O valor do cabeçalho Location
, como mostrado na resposta de exemplo acima, é o URI de sessão que você usará como endpoint HTTP para realizar o upload real do arquivo ou consultar o status de upload.
Copie e salve o URI da sessão para que você possa usá-lo para solicitações subsequentes.
Etapa 3: fazer upload do arquivo
Para fazer upload do arquivo, envie uma solicitação PUT
para o URI de upload recebido na etapa anterior. O formato da solicitação de upload é:
PUT session_uri
Os cabeçalhos HTTP a serem usados ao fazer as solicitações de upload de arquivos retomável incluem Content-Length
. Defina-o como o número de bytes que você está enviando nessa solicitação, que geralmente é o tamanho do arquivo de upload.
Exemplo: solicitação de upload de arquivo retomável
Veja abaixo uma solicitação retomável para fazer upload de todo o arquivo CSV, JSON, AVRO, PARQUET ou ORC de 2.000.000 bytes para o exemplo atual.
PUT https://www.googleapis.com/upload/bigquery/v2/projects/projectId/jobs?uploadType=resumable&upload_id=xa298sd_sdlkj2 HTTP/1.1 Content-Length: 2000000 Content-Type: */* bytes 0-1999999
Se a solicitação for bem-sucedida, o servidor responderá com um HTTP 201 Created
, juntamente com todos os metadados associados a esse recurso. Se a solicitação inicial da sessão retomável fosse PUT
, a resposta de sucesso seria 200 OK
para atualizar um recurso atual, juntamente com todos os metadados associados a ele.
Se a solicitação de upload for interrompida ou se você receber uma resposta HTTP 503 Service Unavailable
ou qualquer outra 5xx
do servidor, siga o procedimento descrito em Retomar um upload interrompido.
Como fazer upload do arquivo em partes
Com os uploads recuperáveis, é possível dividir um arquivo em partes e enviar várias solicitações para fazer upload de cada parte em sequência. Essa não é a abordagem preferida, já que há custos de desempenho associados às outras solicitações, o que geralmente não é necessário. No entanto, talvez seja necessário usar a divisão em partes para reduzir a quantidade de dados transferidos em qualquer solicitação única. Isso é útil quando há um limite de tempo fixo para solicitações individuais, como acontece para determinadas classes de solicitações do Google App Engine. Isso também permite que você faça tarefas como fornecer indicações de progresso de upload para navegadores legados que não são compatíveis com progresso de upload por padrão.
Retomar um upload interrompido
Se uma solicitação de upload for encerrada antes de receber uma resposta ou se você receber uma resposta HTTP 503 Service Unavailable
do servidor, será necessário retomar o upload interrompido. Para fazer isso:
- Solicite o status. Consulte o status atual do upload enviando uma solicitação
PUT
vazia para o URI de upload. Para essa solicitação, os cabeçalhos HTTP precisam incluir um cabeçalhoContent-Range
indicando que a posição atual no arquivo é desconhecida. Por exemplo, definaContent-Range
como*/2000000
se o tamanho total do arquivo for 2.000.000. Se você não souber o tamanho total do arquivo, definaContent-Range
como*/*
.Observação: é possível solicitar o status entre as partes, não apenas se o upload for interrompido. Isso é útil, por exemplo, se você quer mostrar as indicações do progresso de upload para navegadores legados.
- Verifique o número de bytes enviados. Processe a resposta da consulta de status. O servidor usa o cabeçalho
Range
na resposta para especificar quantos bytes recebeu até o momento. Por exemplo, um cabeçalhoRange
de0-299999
indica que os primeiros 300.000 bytes do arquivo foram recebidos. - Envie os dados restantes. Por fim, agora que você sabe de onde retomar a solicitação, envie os dados restantes ou a parte atual. Observe que é necessário tratar os dados restantes como um bloco separado nos dois casos. Portanto, você precisa enviar o cabeçalho
Content-Range
quando retomar o upload.
Exemplo: como retomar um upload interrompido
1) Solicite o status do upload.
A seguinte solicitação usa o cabeçalho Content-Range
para indicar que a posição atual no arquivo de 2.000.000 bytes é desconhecida.
PUT {session_uri} HTTP/1.1 Content-Length: 0 Content-Range: bytes */2000000
2) Extraia o número de bytes enviados da resposta até o momento.
A resposta do servidor usa o cabeçalho Range
para indicar que ele recebeu os primeiros 43 bytes do arquivo até o momento. Use o valor superior do cabeçalho Range
para determinar onde iniciar o upload retomado.
HTTP/1.1 308 Resume Incomplete Content-Length: 0 Range: 0-42
Observação: a resposta de status poderá ser 201 Created
ou 200 OK
se o upload estiver concluído. Isso pode acontecer em caso de falha na conexão após o envio de todos os bytes, mas antes que o cliente receba uma resposta do servidor.
3) Retome o upload do ponto em que parou.
A solicitação a seguir retoma o upload enviando os bytes restantes do arquivo, começando pelo byte 43.
PUT {session_uri} HTTP/1.1 Content-Length: 1999957 Content-Range: bytes 43-1999999/2000000 bytes 43-1999999
Práticas recomendadas
Ao fazer upload de mídia, considere algumas práticas recomendadas relacionadas ao tratamento de erros.
- Retome ou repita os uploads que falharem devido a interrupções na conexão ou a erros
5xx
, incluindo:500 Internal Server Error
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
- Use uma estratégia de espera exponencial se algum erro de servidor
5xx
for retornado ao retomar ou repetir solicitações de upload. Esses erros podem ocorrer quando um servidor fica sobrecarregado. A espera exponencial pode ajudar a aliviar esses tipos de problemas durante períodos de alto volume de solicitações ou tráfego de rede intenso. - Outros tipos de solicitações não podem ser tratados por espera exponencial, mas você ainda pode repetir vários deles. Ao repetir essas solicitações, limite o número de repetições. Por exemplo, o código pode ter o limite de dez tentativas ou menos antes de informar um erro.
- Trate os erros
404 Not Found
e410 Gone
ao fazer uploads retomáveis iniciando o upload completo desde o início.
Espera exponencial
A espera exponencial é uma estratégia padrão de tratamento de erros para aplicativos de rede em que o cliente repete periodicamente uma solicitação com falha ao longo de um período crescente. Se um alto volume de solicitações ou o tráfego de rede intenso faz com que o servidor retorne erros, a espera exponencial pode ser uma boa estratégia para tratar esses erros. Por outro lado, essa não é uma estratégia relevante para tratar erros não relacionados ao volume de rede ou a tempos de resposta, como credenciais de autorização inválidas ou erros de arquivo não encontrado.
Usada corretamente, a espera exponencial aumenta a eficiência do uso da largura de banda, reduz o número de solicitações necessárias para conseguir uma resposta bem-sucedida e maximiza a capacidade de solicitações em ambientes simultâneos.
O fluxo para implementação da espera exponencial simples é o seguinte:
- Faça uma solicitação para a API.
- Receba uma resposta
HTTP 503
, que indica que você deve repetir a solicitação. - Aguarde 1 segundo + random_number_milliseconds e repita a solicitação.
- Receba uma resposta
HTTP 503
, que indica que você deve repetir a solicitação. - Aguarde 2 segundos + random_number_milliseconds e repita a solicitação.
- Receba uma resposta
HTTP 503
, que indica que você deve repetir a solicitação. - Aguarde 4 segundos + random_number_milliseconds e repita a solicitação.
- Receba uma resposta
HTTP 503
, que indica que você deve repetir a solicitação. - Aguarde 8 segundos + random_number_milliseconds e repita a solicitação.
- Receba uma resposta
HTTP 503
, que indica que você deve repetir a solicitação. - Aguarde 16 segundos + random_number_milliseconds e repita a solicitação.
- Parar. Informe ou registre um erro.
No fluxo acima, random_number_milliseconds é um número aleatório de milissegundos menor ou igual a 1.000. Isso é necessário, uma vez que a introdução de um pequeno atraso aleatório ajuda a distribuir a carga de maneira mais uniforme e evitar a possibilidade de falha do servidor. Após cada espera, é preciso redefinir o valor de random_number_milliseconds.
Observação: a espera é sempre (2 ^ n) + random_number_milliseconds, em que n é um número inteiro monótono crescente inicialmente definido como 0. O número inteiro n é incrementado em 1 para cada iteração (cada solicitação).
O algoritmo é definido para terminar quando n for 5. Esse limite impede que os clientes fiquem tentando infinitamente e gera um atraso total de cerca de 30 segundos antes de uma solicitação ser considerada "um erro irrecuperável". Um número máximo maior de tentativas não é um problema, especialmente se um upload longo estiver em andamento. No entanto, use um atraso de repetição aceitável, por exemplo, menos de um minuto.