Spring Data Rest: Return Resources of User

2.4k views Asked by At

I'm creating a simple CRUD-App (a shoppinglist) with Spring Boot and Spring Data Rest. I have a resource: ShoppingItem. Is there an easy way to only return the resources which belong to the user who send the request? (Multiple User support) So a User only get his own ShoppingItems and not every ShoppingItem. Or do i have to implement a Controller by myself, where i do this?

I found Spring Data REST filtering data based on the user this approach for filtering resources based on the user, but this won't help me for the repository endpoint.

Thanks in advance

3

There are 3 answers

6
Kakawait On BEST ANSWER

If you are using Spring security integration you can use ACL (maybe to heavy) or simple postFilter like following:

public interface ShoppingItemRepository extends CrudRepository<ShoppingItem, Long> {
    @PostFilter("filterObject.user.getId() == principal.id")
    @Override
    Iterable<ShoppingItem> findAll();   
}
2
WeMakeSoftware On

You better implement a Controller for several reasons:

  • Imagine your application has some sort of management interface to look through all shopping lists (smth like admin account)

  • Or you need to manipulate the shopping list in some cron-based job (where the uses is missing)

  • business rules in code is better for learning new project (i.e. not all junior programmers can cope with spring magic easily)

Downsides to note:

0
pdorgambide On

I solved this issue recently, see Spring Data Rest Override Repositories (Controllers vs AOP)

The most elegant solution that I found was using AOP, this sample with QueryDSL and Spring Data REST Repositories:

@Aspect
@Transactional
@Component
public class FilterProjectsAspect {

@Pointcut("execution(*  com.xxx.ProjectRepository.findAll(..))")
    public void projectFindAll() {
    }

    @Around("projectFindAll()")
    public Object  filterProjectsByUser(final ProceedingJoinPoint pjp) throws Throwable {

        Object[] args = pjp.getArgs();
        for (int i = 0; i < args.length; i++) {
            if (args[i] instanceof Predicate) {
                Predicate predicate=(Predicate) args[i];
                BooleanExpression isProjectOwner =buildExpressionForUser()
                predicate = ExpressionUtils.allOf(isProjectOwner, predicate);
                args[i]=predicate;  //Update args
            }
        return pjp.proceed(args);
    }

}