Otimização de performance em APIs RESTful (Parte 2)

Bem-vindo à segunda e última parte da série sobre otimização de performance em APIs REST. No post anterior, abordamos duas técnicas/padrões para otimizar sua API: o cache e os retornos assíncronos. Se você ainda não leu a primeira parte, ainda da tempo! Pare um pouquinho e leia. Ela é indispensável para você compreender o artigo como um todo, e introduz alguns conceitos essenciais para você e para a saúde de sua API.

Nesta parte, abordarei mais dois tópicos importantíssimos nesse tipo de discussão: as respostas parciais e os updates parciais. De “brinde”, ainda vou deixar algumas ferramentas que podem te ajudar a analisar a performance da sua aplicação e tomar decisões baseadas nestes resultados. Como sempre, abra sua IDE, pegue um café, e mãos à obra!

1 – RESPOSTAS PARCIAIS

Imagine uma tabela no banco de dados que armazena pessoas, possuindo mais de 10 campos, e você, cliente de uma API, precisa listar o nome dessas pessoas. Supondo o endpoint /pessoas, o método GET traria todas as pessoas cadastradas. Só precisamos do nome de cada pessoa, e para cada pessoa, teríamos o retorno de todos os campos! Isso traria um atraso na resposta muito incômodo para nossa aplicação. O desenvolvedor da API precisa pensar em casos como este e preparar, sem fugir aos princípios do RESTful, endpoints que permitam ao cliente da API selecionar os campos que ele deseja buscar.

A forma mais semântica de se fazer isso é com parâmetros query na URL. Por exemplo, /pessoas?fields=nome,email deveria retornar o nome e o email de todas as pessoas cadastradas no banco. No nosso exemplo, o parâmetro /pessoas?fields=nome serviria, e o volume de dados trocados com o serviço seria absurdamente menor. Utilizando o Spring MVC, faríamos isto com a anotação @RequestParam:

@RequestMapping(value = "/pessoas", method = RequestMethod.GET)
public List<Pessoa> getPessoas(@RequestParam(name = "fields", required = false) String[] fields) {

	if (fields == null)
		// Código antigo para retornar todos os dadados das pessoas
	else
		// Código que retorna somente os campos informados em fields
}

Além deste tipo de resposta parcial, também podemos utilizar paginação diretamente no request. Vamos entender: se em uma página o cliente da API só necessita exibir as 10 primeiras pessoas, por que retornar para ele todas as pessoas cadastradas? O jeito mais simples de fazer essa paginação é com parâmetros na query, como size para definir a quantidade de registros por página, e page para definir qual página está sendo requerida. Por exemplo, um GET na URL /pessoas?fields=nome&size=10&page=1 deveria retornar somente o nome das 10 primeiras pessoas cadastradas no banco de dados. Se o parâmetro page fosse 2, retornaria o nome das próximas 10 pessoas, e assim por diante. Estamos diminuindo cada vez mais a quantidade de dados que são trocados com a API, além de facilitar o desenvolvimento da paginação na aplicação cliente! Isso, sem sobra de dúvidas, é otimização. Você pode usar o número de parâmetros query que quiser, mas lembre-se: não é bom abusar!

Detalhe: em respostas parciais do tipo paginação, é uma boa prática retornar o código http 206: o Partial Response. Esse código é importante para informar ao cliente da API que existem mais registros além dos que foram retornados no atual request.

2 – UPDATES PARCIAIS

Um pouco parecida com a ideia do 3º tópico, vamos pensar em como funciona um update utilizando uma API REST. Imagine você, cliente da mesma API anterior, desejando fazer o update do email de uma pessoa. Simplesmente o email. Normalmente, vocề enviaria uma requisição PUT com todos os dados da pessoa e somente o email modificado. Será realmente necessário enviar todos os dados da pessoa? E se você pudesse enviar somente o email modificado para o endpoint que representa a pessoa?

Felizmente, existe um método http para isso: o PATCH. Esse método pressupõe um update parcial dos dados de um recurso, e não de todos os dados. Preparando a API para otimizar esse processo, sem necessitar dessa transferência de todos os dados da pessoa, um endpoint que aceite o método PATCH somente com os dados que serão modificados bastaria. A diferença pode parecer pequena, mas em ambientes mobile, onde o fluxo de dados é mais caro e restrito, pode fazer toda a diferença. Tudo o que o cliente da API fará é enviar o email atualizado para o endpoint com o método PATCH ao invés do PUT. Simples assim. Novamente, com o Spring MVC, a coisa praticamente não muda. É só criar um endpoint que aceite o método PATCH e o objeto que você quer atualizar no body.

@RequestMapping(value = "/alunos/{id}", method = RequestMethod.PATCH)
public void update(@RequestBody Pessoa pessoa, @PathVariable("id") Long id) {
	// Código que atualiza somente os dados 
	// da pessoa que  foram passados pelo body
}

Claro que essa abordagem tem algumas consequências. O custo de implementação fica mais caro, obviamente, além de aumentar a documentação e a complexidade da API. O uso ou não dessa abordagem (assim como todas as outras já apresentadas aqui) deve ser discutido com a equipe de desenvolvimento e olhando para a necessidade de quem utilizará a API.

3 – EXTRAS

Obviamente, verificar a performance de uma API “na mão” não é muito intuitivo. Caso você queira ferramentas que facilitem esse processo, a LoadUI e a APImetrics podem te ajudar, já que conseguem testar com facilidade a velocidade, escalabilidade e performance de sua API, podendo fazer requisições em massa, testar sistema de segurança, trazer dados de fácil compreensão, automatizar monitoramento da API, etc.

REFERÊNCIAS

https://developers.google.com/drive/v2/web/performance

http://apimetrics.io/

https://www.loadui.org/

http://farazdagi.com/blog/2014/rest-long-running-jobs/

Por DIEGO FERNANDES DE ABREU

Técnico em Processamento de Dados pelo Cotuca, MATERANO com orgulho. Apaixonado por novas tecnologias, música e literatura.

Postado em: 07 de abril de 2016

Confira outros artigos do nosso blog

[Webinar] Profile de aplicações Java com Oracle Mission Control e Flight Recorder

24 de julho de 2017

Danival Calegari

Criando Mocks de serviços REST com SoapUI

27 de junho de 2017

Monise Costa

Three laws that enable agile software development

09 de março de 2017

Celso Gonçalves Junior

Medindo performance de uma API REST

21 de fevereiro de 2017

Monise Costa

Deixe seu comentário