Files
spring-data-examples/rest/uri-customization
Oliver Gierke 4164bc4607 #297 - Upgraded to Boot 2.0 and Spring Data Kay.
Bumped version number to 2.0. Upgraded to Spring Boot 2.0.

Stuff disabled in the meantime:

- Cassandra: needs API adaptions in configuration
- JPA > Security: test fails with weird Hibernate error
- Redis > Reactive: API updates needed
- Solr: configration updates necessary

adjust versions

Updated elastic search to the new version.

Fixed the reactor version to Bismuth-BUILD-SNAPSHOT. This probably should be undone when boot references the proper bom.
2017-10-06 15:15:53 +02:00
..

= Spring Data REST URI customizations

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`:

[source, java]
----
@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:

[source, java]
----
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:

[source, java]
----
@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.