Reputation: 5
We have a concern exposing internal IDs to the outside world. Therefore I'm thinking about using a hashing mechanism (current choice is hashids) to hash our IDs.
I tried to use a @JsonSerializer and @JsonDeserializer mapping on the Entities ID field. But this only takes effect when including the ID in the body, and has no impact on the IDs in the URL paths.
Is there a possibility to do this, e.g. something like an ID Translation SPI?
Upvotes: 0
Views: 1952
Reputation: 1206
Possibly look at https://github.com/fehnomenal/hashids-spring-boot-starter
public class UserModel {
@Hashids(salt = "abc", minHashLength = 8, alphabet = "abcdefghijklmnopqrstuvwxyz")
public long id;
public String name;
}
Upvotes: 0
Reputation: 96
You could try using a converter.
@Component
@AllArgsConstructor
public class HashIdConverter implements Converter<String, Long> {
private final HashidsUtil hashidsUtil;
@Override
public Long convert(@NonNull String source) {
return hashidsUtil.decodeId(source);
}
}
Using it the way I just showed you is a bit unsafe, but it can do the work quite well if you are careful enough
Upvotes: 0
Reputation: 30439
What you need is working "right from the box" in Spring Data REST by customizing item resource URIs:
@Configuration
public class RestConfigurer extends RepositoryRestConfigurerAdapter {
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.withEntityLookup().forRepository(ModelRepo.class, model -> HashIdUtil.encode(model.getId()), ModelRepo::findByEncodedId);
super.configureRepositoryRestConfiguration(config);
}
}
public interface ModelRepo extends JpaRepository<Model, Long> {
default Model findByEncodedId(String encodedId) {
return getById(HashIdUtil.decode(encodedId));
}
Model getById(Long id);
}
public class HashIdUtil {
private static final Hashids HASHIDS = new Hashids("salt", 8);
public static String encode(Long source) {
return HASHIDS.encode(source);
}
public static Long decode(String source) {
return HASHIDS.decode(source)[0];
}
}
Unfortunately, due to the bug (I suppose), PUT/PATCH-ing entities does not work in Spring Boot 2+, unlike the previous version of SB (1.5+) where it works as expected.
See my demo: sdr-hashids-demo
Upvotes: 0
Reputation: 5063
The only thing I can think of is to create a request filter that would take the request with encoded ID in URL, then decode the ID and redirect to an URL with decoded ID.
Upvotes: 0