Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Data Rest custom argument Resolver

So i am trying to add a custom argument resolver to my Spring-Data-Rest project. I am devolping a multi-tenant application, and need to filter data based on a users tenant-id. So i wrote a simple annotation and ArgumentResolver to query my tenant repository and inject a tenant Object as Parameter on some needed Methods:

Handler:

@AllArgsConstructor
public class TenantInjector implements HandlerMethodArgumentResolver {

    private final TenantStore tenantStore;

    private final TenantRepository tenantRepository;


    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        if(! methodParameter.hasParameterAnnotation(InjectTenant.class)) {
            return false;
        }
        return true;
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter,
                                  ModelAndViewContainer modelAndViewContainer,
                                  NativeWebRequest nativeWebRequest,
                                  WebDataBinderFactory webDataBinderFactory) throws Exception {

        return tenantRepository.findById(tenantStore.getId()).get();
    }

}

This handler queries the tenantRepository to find the current tenant by its Id, which is set when the incoming requests security token is parsed.

To register the handler, i do the following:

@Configuration
public class DispatcherContext implements WebMvcConfigurer  {

    private final TenantStore tenantStore;


    private final TenantRepository tenantRepository;

    @Autowired
    public DispatcherContext(TenantStore tenantStore, TenantRepository tenantRepository) {
        this.tenantStore = tenantStore;
        this.tenantRepository= tenantRepository;
    }

    @Override
    public void addArgumentResolvers(
            List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new TenantInjector(tenantStore, tenantRepository));
    }
}

This works nice as long as the corrensponding Controller is annotated with either @Controller or @RestController

As the @RepositoryRestController has an other context, this configuration is ignored. How can I add the same ArgumentResolver to the Spring-Data-Rest configuration?

It might be an option to just switch the annotations, but i would like to rather stick with this approche, as links get generated by spring-data-rest.

Has anyone stumble over this to?

like image 635
Florian Fuchs Avatar asked Sep 02 '25 10:09

Florian Fuchs


1 Answers

Your issue could be that you registered your custom argument resolver in your WebMvcConfigurer. Spring Data Rest seems to work in a different context, so you have to register your custom argument resolver in your RepositoryRestMvcConfiguration.

@Configuration
public class RepositoryConfiguration extends RepositoryRestMvcConfiguration {

    public RepositoryConfiguration(ApplicationContext context, ObjectFactory<ConversionService> conversionService)
    {
        super(context, conversionService);
    }

    @Override
    protected List<HandlerMethodArgumentResolver> defaultMethodArgumentResolvers()
    {
        List<HandlerMethodArgumentResolver> resolvers = 
            new ArrayList<>(super.defaultMethodArgumentResolvers());
        resolvers.add(new TenantInjector(tenantStore, tenantRepository));
        return resolvers;
    }
}

Answer inspired by: https://github.com/tkaczmarzyk/specification-arg-resolver/issues/6#issuecomment-111952898

like image 92
Hugo Leao Avatar answered Sep 05 '25 01:09

Hugo Leao