Este documento aborda algumas técnicas que você pode usar para melhorar o desempenho do aplicativo. Em alguns casos, exemplos de outras APIs ou de APIs genéricas são usados para ilustrar as ideias apresentadas. No entanto, os mesmos conceitos são aplicáveis à API Google Drive.
Compactação com o gzip
Uma maneira fácil e conveniente de reduzir a largura de banda necessária a cada solicitação é ativar a compactação gzip. Embora isso exija mais tempo de CPU para descompactar os resultados, a redução dos custos de rede normalmente faz com que esse método valha muito a pena.
Para receber uma resposta codificada em gzip, você precisa definir um cabeçalho Accept-Encoding
e modificar seu user agent para conter a string gzip
. Veja um exemplo de cabeçalhos HTTP formados devidamente para permitir a compactação gzip:
Accept-Encoding: gzip User-Agent: my program (gzip)
Como trabalhar com recursos parciais
Outra maneira de melhorar o desempenho das chamadas da API é enviar e receber somente a parte dos dados que você quer. Assim, evita-se a transferência, a análise e o armazenamento de campos desnecessários no aplicativo para que recursos como rede, CPU e memória sejam usados de maneira mais eficiente.
Há dois tipos de solicitações parciais:
- Resposta parcial: uma solicitação em que você especifica quais campos serão incluídos na resposta. Use o parâmetro de solicitação
fields
. - Patch: uma solicitação de atualização em que você envia somente os campos que serão alterados. Use o verbo HTTP
PATCH
.
Nas seções a seguir são fornecidos mais detalhes sobre como fazer solicitações parciais.
Resposta parcial
Por padrão, depois de processar as solicitações, o servidor envia de volta a representação completa de um recurso. Para melhorar o desempenho, solicite ao servidor o envio apenas dos campos realmente necessários para receber uma resposta parcial.
Para solicitar uma resposta parcial, use o parâmetro de solicitação fields
para especificar os campos a serem retornados. Use esse parâmetro com qualquer solicitação que retorne dados de resposta.
Observe que o parâmetro fields
afeta apenas os dados de resposta. Ele não afeta os dados que você precisa enviar, se houver. Para reduzir a quantidade de dados enviados durante a modificação de recursos, use uma solicitação de patch.
Exemplo
Patch (atualização parcial)
É possível também evitar o envio de dados desnecessários ao modificar recursos. Para enviar dados atualizados apenas nos campos que estiverem sendo alterados, use o verbo HTTP PATCH
. A semântica do patch descrita neste documento é diferente e mais simples do que aquela da implementação de atualização parcial do GData, que é mais antiga.
Veja no pequeno exemplo abaixo como o uso do patch minimiza os dados necessários para fazer uma pequena atualização.
Exemplo
Como processar a resposta para um patch
Após processar uma solicitação de patch válida, a API retorna um código de resposta HTTP 200 OK
com a representação completa do recurso modificado. Caso a API use ETags, o servidor atualizará os valores delas durante o processamento de uma solicitação de patch, como acontece com PUT
.
A solicitação de correção retorna toda a representação do recurso, a menos que você use o parâmetro fields
para reduzir a quantidade de dados retornados.
Se uma solicitação de correção resultar em um novo estado de recurso sintático ou semanticamente inválido, o servidor retornará um código de status HTTP 400 Bad Request
ou 422 Unprocessable Entity
e o estado do recurso permanecerá inalterado. Por exemplo, ao tentar excluir o valor de um campo obrigatório, o servidor retorna um erro.
Notação alternativa quando não houver suporte para o verbo HTTP PATCH
Caso o firewall não permita solicitações de HTTP PATCH
, faça uma solicitação HTTP POST
e configure o cabeçalho de substituição como PATCH
. Veja o exemplo abaixo:
POST https://www.googleapis.com/... X-HTTP-Method-Override: PATCH ...
Diferença entre patch e atualização
Na prática, ao enviar dados para uma solicitação de atualização que usa o verbo HTTP PUT
, basta enviar os campos obrigatórios ou opcionais. Os valores enviados para campos definidos pelo servidor serão ignorados. Embora possa parecer outro método de se fazer uma atualização parcial, esta abordagem tem algumas limitações. Com atualizações que usam o verbo HTTP PUT
, a solicitação falha quando não são fornecidos parâmetros obrigatórios, e remove dados já definidos quando parâmetros opcionais não são informados.
É muito mais seguro usar o patch por esse motivo. Você fornece somente os dados dos campos que quer alterar. Os campos omitidos não são apagados. A única exceção a essa regra ocorre com matrizes ou elementos repetidos. Se você os omite, eles ficam como estão. Se fornece parte deles, o conjunto inteiro é substituído pelo conjunto fornecido.
Solicitações em lote
Este documento mostra como reunir chamadas à API em lote para reduzir o número de conexões HTTP que seu cliente tem que fazer.
Neste documento, falamos especificamente sobre como fazer uma solicitação em lote enviando uma solicitação HTTP. Se, em vez disso, você estiver usando uma biblioteca de cliente do Google para fazer uma solicitação em lote, consulte a documentação da biblioteca de cliente (em inglês).
Visão geral
Cada conexão HTTP feita pelo cliente resulta em certa quantidade de overhead. A API Google Drive é compatível com o agrupamento em lote a fim de permitir que seu cliente faça várias chamadas de API em uma única solicitação HTTP.
Exemplos de situações em que convém usar operações em lote:
- Recuperar metadados de um grande número de arquivos.
- Atualizar metadados ou propriedades em massa.
- Mudar as permissões de um grande número de arquivos, como adicionar um novo usuário ou grupo.
- Sincronizar dados do cliente local pela primeira vez ou depois de ficar off-line por um longo período.
Em cada caso, em vez de enviar cada chamada separadamente, você pode agrupá-las em uma única solicitação HTTP. Todas as solicitações internas precisam ser encaminhadas para a mesma API do Google.
O limite é de 100 chamadas em uma única solicitação em lote. Se você precisar fazer mais chamadas, use várias solicitações em lote.
Observação: o sistema em lote da API Google Drive usa a mesma sintaxe do sistema de processamento em lote OData, mas a semântica é diferente.
Outras restrições incluem:
- Solicitações em lote com mais de 100 chamadas podem causar um erro.
- Há um limite de 8.000 caracteres no comprimento do URL para cada solicitação interna.
- O Google Drive não é compatível com operações em lote para mídia, seja para upload ou download, ou para exportação de arquivos.
Detalhes do lote
Uma solicitação em lote consiste em várias chamadas de API combinadas em uma solicitação HTTP, que pode ser enviada ao batchPath
especificado no documento de descoberta de API (em inglês). O caminho padrão é /batch/api_name/api_version
. Nesta seção, você verá a descrição em detalhes da sintaxe do lote e, em seguida, um exemplo.
Observação: um conjunto de n solicitações em lote é contabilizado no seu limite de uso, como n solicitações, e não como uma única solicitação. A solicitação em lote é separada em um conjunto de solicitações antes do processamento.
Formato de uma solicitação em lote
Uma solicitação em lote é uma única solicitação HTTP padrão que contém várias chamadas da API Google Drive usando o tipo de conteúdo multipart/mixed
. Dentro dessa solicitação HTTP principal, cada parte contém uma solicitação HTTP aninhada.
Cada parte começa com seu próprio cabeçalho HTTP Content-Type: application/http
. Também é possível ter um cabeçalho Content-ID
opcional. No entanto, os cabeçalhos das partes estão lá apenas para marcar o início da parte. Eles são separados da solicitação aninhada. Depois que o servidor desencapsular a solicitação em solicitações separadas, os cabeçalhos das partes serão ignorados.
O corpo de cada parte é uma solicitação HTTP completa, com o próprio verbo, URL, cabeçalhos e corpo. A solicitação HTTP precisa conter apenas a parte do caminho do URL. URLs completos não são permitidos em solicitações em lote.
Os cabeçalhos HTTP da solicitação em lote externa, exceto os cabeçalhos Content-
, como Content-Type
, aplicam-se a todas as solicitações no lote. Se você especificar um determinado cabeçalho HTTP na solicitação externa e em uma chamada individual, o valor do cabeçalho da chamada individual substituirá o valor do cabeçalho da solicitação em lote externa. Os cabeçalhos de uma chamada individual aplicam-se somente a ela.
Por exemplo, se você fornecer um cabeçalho de autorização para uma chamada específica, esse cabeçalho só se aplicará a essa chamada. Se você fornecer um cabeçalho de autorização para a solicitação externa, esse cabeçalho se aplicará a todas as chamadas individuais, a menos que ele seja substituído por cabeçalhos de autorização próprios.
Ao receber a solicitação em lote, o servidor aplica os parâmetros e os cabeçalhos de consulta da solicitação externa (conforme apropriado) a cada parte e trata cada parte como se fosse uma solicitação HTTP separada.
Resposta a uma solicitação em lote
A resposta do servidor é uma única resposta HTTP padrão com um tipo de conteúdo multipart/mixed
. Cada parte refere-se à resposta a uma das solicitações na solicitação em lote, na mesma ordem das solicitações.
Assim como as partes na solicitação, cada parte da resposta contém uma resposta HTTP completa, inclusive código de status, cabeçalhos e corpo. E da mesma forma que as partes na solicitação, cada parte da resposta é precedida por um cabeçalho Content-Type
que marca o início da parte.
Se uma determinada parte da solicitação tiver um cabeçalho Content-ID
, a parte correspondente da resposta terá um cabeçalho Content-ID
correspondente, com o valor original precedido pela string response-
, conforme mostrado no exemplo a seguir.
Observação: o servidor pode realizar as chamadas em qualquer ordem. Não conte com a execução delas na ordem especificada. Se quiser garantir que duas chamadas ocorram em uma determinada ordem, não as envie em uma única solicitação. Em vez disso, envie a primeira e aguarde a resposta antes de enviar a segunda.
Exemplo
O exemplo a seguir mostra o uso de lotes com a API Google Drive.
Exemplo de solicitação em lote
POST https://www.googleapis.com/batch/drive/v3 Accept-Encoding: gzip User-Agent: Google-HTTP-Java-Client/1.20.0 (gzip) Content-Type: multipart/mixed; boundary=END_OF_PART Content-Length: 963--END_OF_PART Content-Length: 337 Content-Type: application/http content-id: 1 content-transfer-encoding: binary
POST https://www.googleapis.com/drive/v3/files/fileId/permissions?fields=id Authorization: Bearer authorization_token Content-Length: 70 Content-Type: application/json; charset=UTF-8
{ "emailAddress":"example@appsrocks.com", "role":"writer", "type":"user" } --END_OF_PART Content-Length: 353 Content-Type: application/http content-id: 2 content-transfer-encoding: binary
POST https://www.googleapis.com/drive/v3/files/fileId/permissions?fields=id&sendNotificationEmail=false Authorization: Bearer authorization_token Content-Length: 58 Content-Type: application/json; charset=UTF-8
{ "domain":"appsrocks.com", "role":"reader", "type":"domain" } --END_OF_PART--
Exemplo de resposta em lote
Esta é a resposta à solicitação de exemplo da seção anterior:
HTTP/1.1 200 OK Alt-Svc: quic=":443"; p="1"; ma=604800 Server: GSE Alternate-Protocol: 443:quic,p=1 X-Frame-Options: SAMEORIGIN Content-Encoding: gzip X-XSS-Protection: 1; mode=block Content-Type: multipart/mixed; boundary=batch_6VIxXCQbJoQ_AATxy_GgFUk Transfer-Encoding: chunked X-Content-Type-Options: nosniff Date: Fri, 13 Nov 2015 19:28:59 GMT Cache-Control: private, max-age=0 Vary: X-Origin Vary: Origin Expires: Fri, 13 Nov 2015 19:28:59 GMT--batch_6VIxXCQbJoQ_AATxy_GgFUk Content-Type: application/http Content-ID: response-1
HTTP/1.1 200 OK Content-Type: application/json; charset=UTF-8 Date: Fri, 13 Nov 2015 19:28:59 GMT Expires: Fri, 13 Nov 2015 19:28:59 GMT Cache-Control: private, max-age=0 Content-Length: 35
{ "id": "12218244892818058021i" }
--batch_6VIxXCQbJoQ_AATxy_GgFUk Content-Type: application/http Content-ID: response-2
HTTP/1.1 200 OK Content-Type: application/json; charset=UTF-8 Date: Fri, 13 Nov 2015 19:28:59 GMT Expires: Fri, 13 Nov 2015 19:28:59 GMT Cache-Control: private, max-age=0 Content-Length: 35
{ "id": "04109509152946699072k" }
--batch_6VIxXCQbJoQ_AATxy_GgFUk--
Retornar campos específicos da solicitação
Se você não especificar o parâmetro fields
, o servidor vai retornar um conjunto padrão de campos específicos do método. Por exemplo, o método files.list
retorna apenas os campos kind
, id
, name
e mimeType
.
Os campos padrão retornados podem não ser o que você precisa. Se quiser especificar
quais campos retornar na resposta, use o fields
parâmetro
do sistema.
Para mais informações, consulte Retornar campos
específicos.
Para todos os métodos dos recursos about
, comments
(exceto delete
) e replies
(exceto delete
), é obrigatório definir o parâmetro fields
. Esses métodos não retornam um conjunto padrão de campos.