Com o recurso de upload de mídia, a API Campaign Manager 360 pode armazenar dados na nuvem e disponibilizá-la para o servidor. É possível fazer upload de fotos, vídeos, arquivos PDF, arquivos ZIP e qualquer outro tipo de dados.
Os exemplos fornecidos neste documento mostram o uso do upload de mídia para uma API Farm fictícia. No entanto, os mesmos conceitos se aplicam à API Campaign Manager 360.
Opções de envio
A API Campaign Manager 360 permite fazer o upload de certos tipos de dados binários ou mídia. As características específicas dos dados que podem ser enviados por upload são descritas na página de referência de qualquer método compatível com os uploads de mídia:
- Tamanho máximo do arquivo para upload: a quantidade máxima de dados que pode ser armazenada com esse método.
- Tipos MIME de mídia permitidos: os tipos de dados binários que podem ser armazenados usando esse método.
É possível fazer solicitações de upload de qualquer uma das maneiras a seguir. Especifique o método que você está usando com o parâmetro de solicitação uploadType
.
- Upload simples:
uploadType=media
. Para transferências rápidas de arquivos menores de até 5 MB. - Upload em diversas partes:
uploadType=multipart
. Para transferências rápidas de arquivos menores e metadados. O arquivo é transferido junto com os metadados que o descrevem em uma única solicitação. - Upload retomável:
uploadType=resumable
. Uma opção importante para transferências seguras de arquivos maiores. Com esse método, você usa uma solicitação de início de sessão, que opcionalmente pode incluir metadados. Essa é uma boa estratégia a ser usada na maioria dos aplicativos, já que também funciona para arquivos menores com o custo de uma solicitação HTTP adicional por upload.
Ao fazer o upload de mídia, você usa um URI especial. Na verdade, os métodos que são compatíveis com os uploads de mídia têm dois pontos de extremidade do URI:
- O URI "/upload", para a mídia. O formato do ponto de extremidade do upload é o URI de recurso padrão com um prefixo "/upload". Use esse URI ao transferir os próprios dados de mídia. Exemplo:
POST /upload/farm/v1/animals
. - O URI de recurso padrão, para os metadados. Se o recurso contiver campos de dados, estes serão usados para armazenar os metadados de descrição do arquivo enviado. É possível usar esse URI ao criar ou atualizar valores de metadados. Por exemplo:
POST /farm/v1/animals
.
Upload simples
O método mais fácil de transferir um arquivo é criar uma solicitação de upload simples. Essa opção é útil quando:
- o arquivo é pequeno o suficiente para que o upload possa ser refeito inteiramente se a conexão falhar;
- não há metadados para enviar. Isso pode ocorrer quando você planeja enviar os metadados desse recurso em outra solicitação ou caso nenhum metadado seja compatível nem esteja disponível.
Para usar o upload simples, crie uma solicitação POST
ou PUT
para
o URI /upload do método e adicione o parâmetro de consulta
uploadType=media
. Exemplo:
POST https://www.googleapis.com/upload/farm/v1/animals?uploadType=media
Os cabeçalhos de HTTP que podem ser usados na solicitação do upload simples incluem os seguintes:
Content-Type
. Definido conforme um dos tipos permitidos de dados de mídia do método para upload, especificado na referência da API.Content-Length
. Definido conforme o número de bytes do upload. Não é exigido em caso de uso da codificação de transferência fragmentada.
Exemplo: upload simples
O exemplo a seguir mostra o uso de uma solicitação de upload simples da API Farm fictícia.
POST /upload/farm/v1/animals?uploadType=media HTTP/1.1 Host: www.googleapis.com Content-Type: image/jpeg Content-Length: number_of_bytes_in_file Authorization: Bearer your_auth_token JPEG data
Se a solicitação for bem-sucedida, o servidor retornará o código de status HTTP 200 OK
com todos os metadados:
HTTP/1.1 200 Content-Type: application/json { "name": "Llama" }
Upload em diversas 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 em várias partes, faça uma solicitação POST
ou PUT
para o URI /upload do método e adicione o parâmetro de consulta
uploadType=multipart
. Por exemplo:
POST https://www.googleapis.com/upload/farm/v1/animals?uploadType=multipart
Os cabeçalhos de HTTP de alto nível que podem ser usados na solicitação de upload em diversas partes incluem os seguintes:
Content-Type
. Definido como diversas partes/relacionado e inclui a string limite que você usa para identificar as partes da solicitação.Content-Length
. Definido conforme o número total de bytes no corpo da solicitação. A parte de mídia da solicitação deve ser menor do que o tamanho máximo de arquivo especificado para esse 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 limite, e a última string limite é seguida por dois hifens.
Cada parte da solicitação de várias partes precisa de um cabeçalho Content-Type
adicional:
- 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 de API da lista de tipos permitidos de MIME de mídia e de limites de tamanho do método em relação aos arquivos enviados por upload.
Observação: para criar ou atualizar somente 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/farm/v1/animals
Exemplo: upload em diversas partes
O exemplo abaixo mostra uma solicitação de upload em diversas partes da API Farm fictícia.
POST /upload/farm/v1/animals?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 { "name": "Llama" } --foo_bar_baz Content-Type: image/jpeg JPEG data --foo_bar_baz--
Se a solicitação for bem-sucedida, o servidor retornará o código de status HTTP 200 OK
com todos os metadados:
HTTP/1.1 200 Content-Type: application/json { "name": "Llama" }
Upload retomável
Para transferir arquivos de dados de maneira mais confiável, use o protocolo de upload retomável. Esse protocolo permite retomar uma operação de upload quando uma falha de comunicação interrompe o fluxo de dados. É especialmente útil na transferência de 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 app 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.
As instruções para usar o upload retomável incluem o seguinte:
- Iniciar uma sessão retomável. Faça uma solicitação inicial ao URI de upload que inclua os metadados, se houver.
- Salvar o URI da sessão retomável. Salve o URI de sessão retornado na resposta da solicitação inicial. Ele será usado nas outras solicitações desta sessão.
- Fazer upload do arquivo. Envie o arquivo de mídia ao URI de sessão retomável.
Além disso, os aplicativos que usam o upload retomável devem ter o código para retomar um upload interrompido. Se um upload for interrompido, descubra a quantidade de dados que foi recebida e retome-o daquele ponto.
Observação: o 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
ou PUT
para o URI /upload do método e adicione o parâmetro de consulta
uploadType=resumable
. Por exemplo:
POST https://www.googleapis.com/upload/farm/v1/animals?uploadType=resumable
Para essa solicitação inicial, o corpo está vazio ou contém somente os metadados. Você transfere o conteúdo real do arquivo que quer enviar por upload nas solicitações subsequentes.
Use os seguintes cabeçalhos de HTTP com a solicitação inicial:X-Upload-Content-Type
. Definido de acordo com o tipo MIME de mídia dos dados para upload que serão transferidos nas solicitações subsequentes.X-Upload-Content-Length
. Definido conforme o número de bytes dos dados para upload que serão transferidos nas solicitações subsequentes. Se o tamanho não for conhecido no momento da solicitação, será possível omitir esse cabeçalho.- Se estiver fornecendo metadados:
Content-Type
. Definido de acordo com o tipo de dados dos metadados. Content-Length
. Definido conforme o número de bytes fornecidos no corpo dessa solicitação inicial. Não será exigido se você usar a codificação de transferência fragmentada.
Consulte a referência de API da lista de tipos permitidos de MIME de mídia e de limites de tamanho do método em relação aos arquivos enviados por upload.
Exemplo: solicitação de iniciação da sessão retomável
O exemplo a seguir mostra como iniciar uma sessão retomável da API Farm fictícia.
POST /upload/farm/v1/animals?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: image/jpeg X-Upload-Content-Length: 2000000 { "name": "Llama" }
Observação: para uma solicitação inicial de atualização retomável sem metadados, deixe em branco o corpo da solicitação e defina o cabeçalho Content-Length
como 0
.
A próxima seção descreve como processar a resposta.
Etapa 2: salvar o URI de 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
Aqui está a resposta à solicitação realizada na Etapa 1:
HTTP/1.1 200 OK Location: https://www.googleapis.com/upload/farm/v1/animals?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 de sessão para poder usá-lo nas solicitações subsequentes.
Etapa 3: fazer upload do arquivo
Para fazer upload do arquivo, envie uma solicitação PUT
ao URI de upload que você salvou 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 essa opção conforme o número de bytes incluídos no upload dessa solicitação, que geralmente corresponde ao tamanho do arquivo de que é feito o upload.
Exemplo: solicitação de upload de arquivo retomável
Esta é uma solicitação retomável para fazer upload de todo o arquivo JPEG de 2.000.000 de bytes do exemplo atual.
PUT https://www.googleapis.com/upload/farm/v1/animals?uploadType=resumable&upload_id=xa298sd_sdlkj2 HTTP/1.1 Content-Length: 2000000 Content-Type: image/jpeg bytes 0-1999999
Se a solicitação for bem-sucedida, o servidor responderá com um HTTP 201 Created
e todos os metadados associados a esse recurso. Se a solicitação inicial da sessão retomável tivesse sido PUT
, para atualizar um recurso existente, a resposta correta seria 200 OK
, com todos os metadados associados ao recurso.
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.
Upload do arquivo em fragmentos
Com os uploads retomáveis, é possível dividir um arquivo em fragmentos e enviar diversas solicitações para transferir cada um deles em sequência. Esse não é o método preferido, já que existem custos de desempenho associados às solicitações adicionais que geralmente não são necessários. 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. Essa opção também permite fornecer indicações sobre o andamento do upload para navegadores legados que, por padrão, não disponibilizam o andamento do upload.
Retomar um upload interrompido
Se uma solicitação de upload for encerrada antes de receber uma resposta ou você receber uma resposta de HTTP 503 Service Unavailable
do servidor, será preciso retomar o upload interrompido. Para isso, faça o seguinte:
- 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 fragmentos, não só quando o upload é interrompido. Isso será útil, por exemplo, quando você quiser mostrar indicações do andamento do upload a navegadores legados.
- Descubra o número de bytes transferidos por upload. Processe a resposta do status de consulta. O servidor usa o cabeçalho
Range
na resposta ao especificar quais bytes foram recebidos até agora. Por exemplo, um cabeçalhoRange
de0-299999
indica que os primeiros 300.000 bytes do arquivo foram recebidos. - Faça upload dos dados restantes. Agora que você sabe em que ponto retomar a solicitação, envie os dados restantes ou o fragmento atual. Nos dois casos, trate os dados restantes como um fragmento separado. Será necessário enviar o cabeçalho
Content-Range
ao retomar o upload.
Exemplo: como retomar um upload interrompido
1) Solicite o status de upload.
A seguinte solicitação usa o cabeçalho Content-Range
para indicar que a posição atual no arquivo de 2.000.000 de bytes é desconhecida.
PUT {session_uri} HTTP/1.1 Content-Length: 0 Content-Range: bytes */2000000
2) Extraia da resposta o número de bytes enviados por upload até agora.
A resposta do servidor usa o cabeçalho Range
para indicar que ele recebeu os primeiros 43 bytes do arquivo até agora. Use o valor superior do cabeçalho Range
para determinar em que ponto 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 poderá acontecer quando a conexão for interrompida após o upload de todos os bytes, mas antes de o cliente receber uma resposta do servidor.
3) Retome o upload do ponto onde parou.
A solicitação a seguir retoma o upload enviando os bytes remanescentes do arquivo a partir do 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, conheça algumas das práticas recomendadas referentes à correção de erros.
- Retome ou repita os uploads que falharem devido a interrupções de 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
5xx
do servidor for retornado ao retomar as solicitações de upload ou ao fazer novas tentativas de solicitação. Esses erros podem ocorrer quando o servidor fica sobrecarregado. O backoff exponencial pode ajudar a aliviar esses problemas em períodos de grande volume de solicitações ou intenso tráfego de rede. - Outros tipos de solicitações não devem ser tratados por backoff exponencial, mas ainda é possível tentar emitir novamente alguns deles. Ao tentar realizar novamente essas solicitações, limite o número de tentativas. Por exemplo, seu código pode limitar a 10 tentativas ou menos antes que um erro seja relatado.
- Trate os erros
404 Not Found
e410 Gone
ao fazer uploads retomáveis iniciando o upload completo desde o início.
Espera exponencial
O backoff exponencial é uma estratégia padrão de tratamento de erros para aplicações de rede em que o cliente tenta enviar periodicamente uma solicitação com falha durante um intervalo de tempo crescente. Se um grande volume de solicitações ou um tráfego de rede intenso fizer com que o servidor retorne erros, o backoff exponencial poderá ser uma boa estratégia para tratar esses erros. Por outro lado, não é uma estratégia relevante para lidar com erros não relacionados a volume de rede ou a tempos de resposta, como erros de credenciais de autorização inválidas ou de arquivo não encontrado.
Usado corretamente, o backoff exponencial aumenta a eficiência do uso de largura de banda, reduz o número de solicitações necessárias para receber uma resposta bem-sucedida e potencializa o rendimento de solicitações em ambientes simultâneos.
Veja a seguir o fluxo de implementação de backoff exponencial simples:
- Faça uma solicitação para a API.
- Receba uma resposta
HTTP 503
, que indica que você precisa repetir a solicitação. - Aguarde um segundo + random_number_milliseconds e envie novamente a solicitação.
- Receba uma resposta
HTTP 503
, que indica que você precisa repetir a solicitação. - Aguarde dois segundos + random_number_milliseconds e envie novamente a solicitação.
- Receba uma resposta
HTTP 503
, que indica que você precisa repetir a solicitação. - Aguarde quatro segundos + random_number_milliseconds e envie novamente a solicitação.
- Receba uma resposta
HTTP 503
, que indica que você precisa repetir a solicitação. - Aguarde oito segundos + random_number_milliseconds e envie novamente a solicitação.
- Receba uma resposta
HTTP 503
, que indica que você precisa repetir a solicitação. - Aguarde 16 segundos + random_number_milliseconds e envie novamente a solicitação.
- Pare. Relate ou registre um erro.
No fluxo acima, "random_number_milliseconds" é um número aleatório de milissegundos inferior ou igual a 1.000. Esse procedimento é necessário porque a introdução de um pequeno atraso aleatório ajuda a distribuir a carga de maneira mais uniforme e a evitar a possibilidade de sobrecarrega do servidor. O valor de "random_number_milliseconds" deve ser redefinido após cada período de espera.
Observação: o período de espera sempre é (2 ^ n) + "random_number_milliseconds", em que "n" é um número inteiro monotonicamente crescente, definido inicialmente como 0. O número inteiro "n" é incrementado em 1 a cada solicitação.
O algoritmo é definido para terminar quando n é 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.