NRaf
NRaf

Reputation: 7549

Prevent multiple sort parameters with Pageable in Spring REST Controllers

I'm working an API using Spring Boot and Spring Data repos (although not Spring Data REST).

@GetMapping
public List<Foo> listFoos(
    @SortDefault(value = "name", direction = Sort.Direction.ASC)
    Pageable pageable,
    HttpServletRequest request) {
  FooRepo.findAll(pageable);
}

The above works fine. I can sort fine by passing a sort parameter, however I'm a bit concerned about the performance implications.

I'd like to limit it to only support sort by a single parameter at a time for performance reasons. By default, I can do something like ?sort=name,createdAt which will generate a query to order by both name and createdAt. Given it's a public API, I'm a bit concerned about some users abusing this and attempting to sort by a whole bunch of values that we haven't optimised for.

Secondly, there are some values that don't make sense for sorting. For example, if Foo had a thumbnail URL, it wouldn't make sense to sort by thumbnail. Is there any ability to whitelist or blacklist the sort values?

Upvotes: 1

Views: 2108

Answers (1)

Eugene Maksymets
Eugene Maksymets

Reputation: 156

you can make your CustomSortHandlerMethodArgumentResolver ( implements org.springframework.data.web.SortArgumentResolver spring implementation org.springframework.data.web.SortHandlerMethodArgumentResolver)

@Configuration
@EnableWebMvc
public class WebMvcContext extends WebMvcConfigurerAdapter {

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        PageableArgumentResolverhandler = new PageableHandlerMethodArgumentResolver(
                new CustomSortHandlerMethodArgumentResolver()); 

        argumentResolvers.add(handler);
    } 
}

in custom implementation, you can create white/black lists and customize the processing of the collation so as to you conveniently, and to avoid common mistakes - see the implementation of the spring

one of the ways

public class CustomSortHandlerMethodArgumentResolver extends 
        SortHandlerMethodArgumentResolver{



    @Override
    public Sort resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
        Sort sort = super.resolveArgument(parameter, mavContainer, webRequest, binderFactory);

        /*
            additional logic for filtering orders        
         */

        return sort != null && sort.iterator().hasNext() ? new Sort(sort.iterator().next()) : null;
    }
}

Upvotes: 2

Related Questions