Search code examples
springrestconverterscomposite-id

exposing composite ID through spring rest repository


I Have a domain object with

  • id
  • version

we want to show this in a table, so I need to get it in my rest request.

As suggested, I've implemented a

@Configuration
public class RepoConf extends RepositoryRestMvcConfiguration {

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

    protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
        config.exposeIdsFor(Lot.class);
    }
}

I've checked the log that this conf is loaded:

2017-12-08 07:58:59.966  INFO 10344 --- [  restartedMain] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'httpRequestHandlerAdapter' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=repoConf; factoryMethodName=httpRequestHandlerAdapter; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [fr/urssaf/genv/back/repository/RepoConf.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration; factoryMethodName=httpRequestHandlerAdapter; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]]

I have a converter to handle composite ID in URL:

@Component
class CustomBackendIdConverter implements BackendIdConverter {

    @Override
    public Serializable fromRequestId(String id, Class<?> entityType) {

        switch (entityType.getSimpleName()) {
        case "Lot":
            String[] parts = id.split("_");
            return new LotId(Integer.valueOf(parts[0]), parts[1]);

        default:
            return null;
        }

    }

    @Override
    public String toRequestId(Serializable source, Class<?> entityType) {
        switch (entityType.getSimpleName()) {
        case "Lot":
            LotId id = (LotId) source;
            return String.format("%s_%s", id.getIdLot(), id.getVersionLot());

        default:
            return null;
        }

    }

    @Override
    public boolean supports(Class<?> type) {
        return Lot.class.equals(type);
    }

}

But My Id is not shown when I made a request on Lot rest resource, for example on: http://localhost:9000/lots/1_0 how can I achieve that?


Solution

  • Ok, digging in spring code, it seems that the methods signature off

    RepositoryRestMvcConfiguration
    

    has changed, the correct code to expose IDs is:

    @Configuration
    public class RepoConf extends RepositoryRestMvcConfiguration {
    
        public RepoConf(ApplicationContext context, ObjectFactory<ConversionService> conversionService) {
            super(context, conversionService);
        }
    
        @Override
        public ProfileResourceProcessor profileResourceProcessor(RepositoryRestConfiguration config) {
            config.exposeIdsFor(Lot.class);
            return super.profileResourceProcessor(config);
        }
    
    }
    

    here is my request working on http://localhost:9000/lots/1_0 :

    {
        "id": {
            "idLot": 1,
            "versionLot": "0"
        },
        "descLot": "test col",
        "etatLot": "init",
        "typeLot": "install",
        "userMaj": "bibi",
        "dateMaj": null,
        "livraisonLots": [],
        "environnementLots": [],
        "_links": {
            "self": {
                "href": "http://localhost:9000/lots/1_0"
            },
            "lot": {
                "href": "http://localhost:9000/lots/1_0"
            }
        }
    }