This example shows how to customize which property of the domain type shall be used to create URIs for item resources.
When using Java 8, this is as easy as registering the mapping operations on Spring Data RESTs RepositoryRestConfiguration
:
@Component
public class SpringDataRestCustomization extends RepositoryRestConfigurerAdapter {
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.withCustomEntityLookup().//
forRepository(UserRepository.class, User::getUsername, UserRepository::findByUsername);
}
}
As you can see the EntityLookupRegistrar
obtained via RepositoryrestConfiguration.withCustomEntityLookup()
takes two method references.
The first one defines the identifier mapping, the second one defines how to look up the entity using the repository.
The customization could also be defined in a slightly more explicit way like this:
config.withCustomEntityLookup().
forRepository(UserRepository.class).
withIdMapping(User::getUsername).
withLookup(UserRepository::findByUsername);
In non-Java 8 environments the method references would have to be replaced with a quite verbose anonymous inner class, so that it’s probably easier to implement EntityLookup
explixitly and declare it as Spring bean:
@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired) )
public class UserEntityLookup extends EntityLookupSupport<User> {
private final @NonNull UserRepository repository;
@Override
public Serializable getResourceIdentifier(User entity) {
return entity.getUsername();
}
@Override
public Object lookupEntity(Serializable id) {
return repository.findByUsername(id.toString());
}
}
As you can see the customization consists of two methods that need to be symmetric in their functionality. getResourceIdentifier(…)
returns the property that’s supposed to be used in the URI while lookupEntity(…)
uses the value to lookup an entity via a query method for exactly that property.