Provavelmente, você já precisou buscar algum dado específico em uma API, por exemplo, um intervalo de menor para o maior preço em um site de imóveis. Quando clicou em pesquisa, viu a URL ficar assim:
https://imoveis.com/list?startPrice=300000&andPrice=600000
Isso são query filters, um conjunto pré-determinado de termos que nos ajuda a obter um conjunto exato de resultados que queremos, em vez de todos os resultados sem nenhum critério. Um exemplo bastante comum é a própria paginação, que, por sua vez, utiliza parâmetros como “page” para representar qual página você está buscando e “perPage” para informar a quantidade de elementos por página.
O que é a filtragem?
https://i.pinimg.com/originals/2f/69/54/2f6954149ebdc0bce9480ca8052d6af6.gif
Filtragem nada mais é do que um mecanismo para recuperar resultados fornecendo algum critério. Podemos ter diversos filtros para obter “n” resultados, seja intervalo de valores, intervalo de datas, categoria, ou outra coisa. Ao implementar filtros, você se limita a um conjunto predefinido de opções que você definiu para suas solicitações. Por exemplo, você pode informar o campo “ativo” para buscar apenas usuários que estão ativos, mas, caso não tenha configurado essa opção, ela será simplesmente ignorada.
Se você já navegou em algum site, seja de imóveis, veículos, ou até mesmo no sistema de controle de estoque da sua empresa, já se deparou com uma tela parecida com essa. Esse tipo de abordagem é bastante comum para o front-end, basicamente um formulário com as opções de filtros já definidos na API, e que, ao ser submetido, atualiza o conjunto de dados listado. Por sua vez, isso também limita o usuário a não adicionar campos que não existem, como no exemplo anterior de “ativo”.
Vamos pegar como exemplo um sistema que precisa listar seus clientes. Ao filtrar os clientes, queremos que seja possível selecionar as seguintes opções:
- Buscar clientes que nasceram em uma data
- Listar clientes ativos
Com isso, teremos algo como:
http://localhost:8000/clients?ativo=true&dataAniversario=1999-01-01
Filtragem e pesquisa, parecidos mas não iguais
Ao buscar por resultados, você geralmente tem apenas uma entrada, e é aquela que você usa para pesquisar qualquer coisa dentro do site. Então, basicamente, você envia uma cadeia de caracteres para a API, e a API é responsável por pegar esses dados e encontrar algum resultado. Por exemplo, buscar usuários pelo e-mail, teríamos um campo email=cliente@email.com que, ao chegar na API, iria buscar os registros com um e-mail similar ao informado.
Mas claro, utilizar a pesquisa não significa que você não pode usar filtros. Faz todo sentido você combinar filtros com uma pesquisa, por exemplo, buscar um cliente ativo que possui o e-mail cliente@email.com, teríamos algo assim:
http://localhost:8000/clients?ativo=true&email=cliente@email.com
Implementando filtros em uma WEB API do ASP.NET
https://www.google.com/url?sa=i&url=https%3A%2F%2Ftenor.com%2Fsearch%2Fcoding-gifs&psig=AOvVaw2RG9wcfDwqvaIjXZsAN1EK&ust=1718811402226000&source=images&cd=vfe&opi=89978449&ved=0CBAQjRxqFwoTCNiU0c295YYDFQAAAAAdAAAAABAE
Estou utilizando algumas classes que vimos no artigo sobre paginação, fique à vontade para dar continuidade, mas caso queira entrar mais no contexto, clique aqui.
Vamos começar preparando nosso controller para receber os parâmetros pela query, utilizando nossa classe ClienteParams:
[HttpGet]
public IActionResult GetAll([FromQuery] ClienteParams clienteParams)
{
var clientes = _clienteRepository.GetAll(clienteParams);
return Ok(clientes);
}
Aqui, estamos usando o [FromQuery] para dizer ao framework que os dados de clienteParams estão vindo da query da requisição. Em seguida, chamamos o nosso repository para fazer a busca dos dados (caso você não saiba para que serve esse repository, tenho um post exclusivo para você, basta clicar aqui). Em seguida, apenas retorno o resultado.
Agora, vamos ver nosso ClienteParams:
public class ClienteParams
{
const int maxPageSize = 50;
public int PageNumber { get; set; } = 1;
private int _pageSize = 10;
public string? ativo;
public int PageSize
{
get { return _pageSize; }
set { _pageSize = (value > maxPageSize) ? maxPageSize : value; }
}
}
Primeiro, temos a parte de paginação implementada, e como filtro, vamos ter apenas o “ativo”, que pode receber null (?), tornando-o opcional.
Agora vejamos a implementação do repository:
public IEnumerable<Cliente> GetAll(ClienteParams clienteParams)
{
IQueryable<Cliente> query = _appDbContext.Clientes;
if (!string.IsNullOrEmpty(clienteParams.ativo))
query = query.Where(p => p.ativo == true);
return query
.OrderBy(c => c.Id)
.Skip((clienteParams.PageNumber - 1) * clienteParams.PageSize)
.Take(clienteParams.PageSize)
.ToList();
}
Como podem ver, não há muito nisso. Adicionamos nossa verificação de validação para caso o parâmetro “ativo” seja informado, e usamos ele na query caso exista.
Conclusão
Bem simples, não? O conceito de filtros, apesar de não ser complexo, traz consigo muita praticidade no código, removendo a necessidade de criar rotas específicas para buscas específicas, além de tornar o código mais flexível.
Neste artigo, você aprendeu mais sobre a filtragem de dados pela query da URL e, além disso:
- Aprendeu o que é filtragem de dados
- Para que serve a filtragem de dados
- Diferença entre filtros e busca
- Como implementar filtros em C#