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 Civic Information do Google.
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 forma de melhorar o desempenho das chamadas de API é solicitar apenas a parte dos dados do seu interesse. 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.
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.
Exemplo
O exemplo a seguir mostra o uso do parâmetro fields
com uma API "Demo" genérica (fictícia).
Solicitação simples: essa solicitação HTTP GET
omite o parâmetro fields
e retorna o recurso completo.
https://www.googleapis.com/demo/v1
Resposta de recursos completos: os dados de recursos completos incluem os campos a seguir, além de muitos outros omitidos para agilizar o processo.
{ "kind": "demo", ... "items": [ { "title": "First title", "comment": "First comment.", "characteristics": { "length": "short", "accuracy": "high", "followers": ["Jo", "Will"], }, "status": "active", ... }, { "title": "Second title", "comment": "Second comment.", "characteristics": { "length": "long", "accuracy": "medium" "followers": [ ], }, "status": "pending", ... }, ... ] }
Solicitação de uma resposta parcial: na solicitação a seguir, para esse mesmo recurso, o parâmetro fields
é usado para reduzir de modo significativo a quantidade de dados retornados.
https://www.googleapis.com/demo/v1?fields=kind,items(title,characteristics/length)
Resposta parcial: em reação à solicitação acima, o servidor envia de volta uma resposta que contém somente as informações de tipo, além de uma matriz de itens pareados com características de tamanho e título HTML em cada item.
200 OK
{ "kind": "demo", "items": [{ "title": "First title", "characteristics": { "length": "short" } }, { "title": "Second title", "characteristics": { "length": "long" } }, ... ] }
Observe que a resposta é um objeto JSON que contém apenas os campos selecionados e os respectivos objetos pais.
Veja detalhes sobre como formatar o parâmetro fields
a seguir, seguidos por mais detalhes sobre o que exatamente é retornado na resposta.
Resumo da sintaxe do parâmetro "Campos"
O formato do valor do parâmetro da solicitação fields
baseia-se vagamente na sintaxe XPath. Veja abaixo um resumo da sintaxe compatível e outros exemplos.
- Use uma lista separada por vírgulas para selecionar diversos campos.
- Use
a/b
para selecionar um campob
aninhado no campoa
. Usea/b/c
para selecionar um campoc
aninhado emb
.
Exceção: Para respostas da API que usam wrappers "data", em que a resposta é aninhada em um objeto
data
semelhante adata: { ... }
, não inclua "data
" na especificaçãofields
. A inclusão do objeto de dados com uma especificação de campos comodata/a/b
causa um erro. Em vez disso, basta usar uma especificaçãofields
comoa/b
. - Use um sub-seletor para solicitar um conjunto de subcampos específicos de matrizes ou objetos. Basta colocar expressões entre parênteses "
( )
".Por exemplo:
fields=items(id,author/email)
retorna apenas o ID do item e o e-mail do autor para cada elemento na matriz de itens. Também é possível especificar um único subcampo, em quefields=items(id)
é equivalente afields=items/id
. - Se necessário, use caracteres curinga em seleções de campo.
Por exemplo:
fields=items/pagemap/*
seleciona todos os objetos em um pagemap.
Mais exemplos do uso do parâmetro fields
Os exemplos abaixo incluem descrições de como o valor do parâmetro fields
afeta a resposta.
Observação: assim como com todos os valores de parâmetro de consulta, fields
também precisa ter codificação de URL. Para facilitar a leitura, os exemplos neste documento estão sem a codificação.
- Identifique os campos a serem retornados ou faça seleções de campos.
- O valor de parâmetro da solicitação
fields
é uma lista de campos separados por vírgulas e cada campo é especificado em relação à raiz da resposta. Portanto, se você estiver executando uma operação de lista, a resposta será uma coleção que, geralmente, inclui uma matriz de recursos. Se você estiver executando uma operação que retorne um único recurso, os campos serão especificados em relação a esse recurso. Se o campo selecionado for uma matriz, ou parte dela, o servidor retornará a parte selecionada de todos os elementos na matriz.
Veja alguns exemplos do nível de coleção:
Exemplos Efeito items
Retorna todos os elementos da matriz de itens, incluindo todos os campos em cada elemento, mas nenhum outro campo. etag,items
Retorna o campo etag
e todos os elementos na estrutura de itens.items/title
Retorna apenas o campo de title
para todos os elementos da matriz de itens.
Sempre que um campo aninhado for retornado, a resposta incluirá os respectivos objetos pais. Os campos pai não incluem outro campo filho, a menos que eles também sejam selecionados explicitamente.context/facets/label
Retorna apenas o campo label
para todos os membros da matrizfacets
, que é aninhada sob o objetocontext
.items/pagemap/*/title
Para cada elemento na matriz de itens, retorna apenas o campo title
, se presente, de todos os objetos filhos depagemap
.
Veja alguns exemplos no nível do recurso:
Exemplos Efeito title
Retorna o campo title
do recurso solicitado.author/uri
Retorna o subcampo uri
do objetoauthor
no recurso solicitado.links/*/href
Retorna o campo href
de todos os objetos filhos delinks
. - Solicite apenas partes de campos específicos usando subseleções.
- Por padrão, se houver campos particulares especificados na solicitação, todos os objetos ou elementos da matriz serão retornados pelo servidor. É possível especificar uma resposta que inclua apenas determinados subcampos. Para isso, use a sintaxe de subseleção "
( )
", como no exemplo abaixo.Exemplo Efeito items(title,author/uri)
Retorna apenas os valores de title
euri
do autor para cada elemento na matriz de itens.
Como processar respostas parciais
Depois que o servidor processar uma solicitação válida que inclua o parâmetro de consulta fields
, ele retorna um código de status 200 OK
HTTP, junto com os dados solicitados. Se o parâmetro de consulta fields
tiver um erro ou for inválido, o servidor retornará um código de status HTTP 400 Bad Request
com uma mensagem informando ao usuário o que havia de errado com a seleção de campos. Por exemplo, "Invalid field selection a/b"
.
Veja o exemplo de resposta parcial mostrado na seção introdutória acima. A solicitação usa o parâmetro fields
para especificar os campos que precisam ser retornados.
https://www.googleapis.com/demo/v1?fields=kind,items(title,characteristics/length)
A resposta parcial é semelhante a esta:
200 OK
{ "kind": "demo", "items": [{ "title": "First title", "characteristics": { "length": "short" } }, { "title": "Second title", "characteristics": { "length": "long" } }, ... ] }
Observação: em APIs compatíveis com parâmetros de consulta para paginação de dados (por exemplo, maxResults
e nextPageToken
), use esses parâmetros para reduzir os resultados de cada consulta a um tamanho administrável. Caso contrário, os possíveis ganhos de desempenho talvez não se concretizem.