Skip to content

Instantly share code, notes, and snippets.

@alexxfreitag
Last active January 24, 2022 21:45
Show Gist options
  • Save alexxfreitag/0bf128de8a3bdbd81367e20348c1fa6f to your computer and use it in GitHub Desktop.
Save alexxfreitag/0bf128de8a3bdbd81367e20348c1fa6f to your computer and use it in GitHub Desktop.
Passo a passo de como configurar/utilizar o specification-arg-resolver, biblioteca focada em filtros de API.

Dependência Maven da biblioteca (https://github.com/tkaczmarzyk/specification-arg-resolver):

<dependency>
  <groupId>net.kaczmarzyk</groupId>
  <artifactId>specification-arg-resolver</artifactId>
  <version>2.6.2</version>
</dependency>

Configuração e uso

  1. Criar uma classe de configuração (exemplo: configs/ResolverConfig.java):

    @Configuration
    public class ResolverConfig extends WebMvcConfigurationSupport {
    
        @Override
        protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
            argumentResolvers.add(new SpecificationArgumentResolver());
    
            PageableHandlerMethodArgumentResolver resolver = new PageableHandlerMethodArgumentResolver();
            argumentResolvers.add(resolver);
    
            super.addArgumentResolvers(argumentResolvers);
        }
    }
  2. Criar uma classe com os templates (que são interfaces) de specification (exemplo: specifications/SpecificationTemplate.java):

    public class SpecificationTemplate {
    
        @And({
                @Spec(path = "courseLevel", spec = Equal.class),
                @Spec(path = "courseStatus", spec = Equal.class),
                @Spec(path = "name", spec = Like.class)
        })
        public interface CourseSpec extends Specification<CourseModel> {}
    }
    • Nessa classe de template, deve ser criado uma interface para cada tipo de entidades na qual se deseja utilizar o specification. O filtro é aplicado com a anotação @Spec, que deve possuir o nome da coluna desejada no path e o tipo de filtro no spec, conforme mostrado no código acima.
    • Além disso, é possível a anotação @Spec estar dentro da anotação @And ou @Or, variando conforme a necessidade de combinar todos os filtros aplicados ou aceitar apenas um desses filtros.
  3. Estender o JpaSpecificationExecutor no repositório JPA da(s) entidade(s) que irá(ão) utilizar os filtros de specification:

    public interface CourseRepository extends JpaRepository<CourseModel, UUID>, JpaSpecificationExecutor<CourseModel> {}
  4. Receber como parâmetro no controller o template e utilizar como parâmetro na consulta desejada (neste exemplo, o findAll()):

    public List<CourseModel> getAllCourses(SpecificationTemplate.CourseSpec courseSpec) {
    	return courseRepository.findAll(courseSpec);
    }
    • Como o repositório passou a estender o JpaSpecificationExecutor, o método findAll(Specification<T> spec) passou a ficar disponível para ser usado automaticamente.

Exemplo de requisição com filtros (cURL):

$ curl --location --request GET 'http://localhost:8082/courses?courseStatus=INPROGRESS&courseLevel=BEGINNER'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment